React Native: Можливе неприйняте обіцянку


82

Я отримую таку помилку: Possible unhandled promise rejection (id:0: Network request failed

Ось код обіцянки, я не бачу, що тут не так, будь-які ідеї?

  return fetch(url)
    .then(function(response){
      return response.json();
    })
    .then(function(json){
      return {
        city: json.name,
        temperature: kelvinToF(json.main.temp),
        description: _.capitalize(json.weather[0].description)
      }
    })
    .catch(function(error) {
    console.log('There has been a problem with your fetch operation: ' + error.message);
    });
}

** Редагувати: я додав функцію catch та отримав кращу помилку You passed an undefined or null state object; instead, use forceUpdate(). index.ios.js:64 undefined

Ось код index.ios.js. URL-адреса чудова і дає мені правильні дані JSON. За допомогою журналу консолі я бачу, що і те, region.latitudeі інше region.longitudeдоступне в Api(region.latitude, region.longitude). Але dataне визначено. Я досі не впевнений, що відбувається, чому виникає проблема dataі чому вона невизначена.

// var React = require('react-native'); --deprecated

// updated
import React from 'react';

// updated
import {
  AppRegistry,
  MapView,
  View,
  Text,
  StyleSheet,
} from 'react-native';

/*
var {
  AppRegistry,
  MapView,
  View,
  Text,
  StyleSheet
} = React;
*/ // -- depreciated 


var Api = require('./src/api');

var Weather = React.createClass({
  getInitialState: function() {
    return {
      pin: {
        latitude: 0,
        longitude: 0
      },
      city: '',
      temperature: '',
      description: ''
    };
  },
  render: function() {
    return <View style={styles.container}>
      <MapView
        annotations={[this.state.pin]}
        onRegionChangeComplete={this.onRegionChangeComplete}
        style={styles.map}>
      </MapView>
      <View style={styles.textWrapper}>
        <Text style={styles.text}>{this.state.city}</Text>
        <Text style={styles.text}>{this.state.temperature}</Text>
        <Text style={styles.text}>{this.state.description}</Text>
      </View>
    </View>
  },
  onRegionChangeComplete: function(region) {
    this.setState({
      pin: {
        longitude: region.longitude,
        latitude: region.latitude
      }
    });

    Api(region.latitude, region.longitude)
      .then((data) => {
        console.log(data);
        this.setState(data);
      });
  }
});




var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'stretch',
    backgroundColor: '#F5FCFF'
  },
  map: {
    flex: 2,
    marginTop: 30
  },
  textWrapper: {
    flex: 1,
    alignItems: 'center'
  },
  text: {
    fontSize: 30
  }
});

AppRegistry.registerComponent('weather', () => Weather);

3
додайте .catch()також і перевірте, чи помилка зникає. посилання: facebook.github.io/react-native/docs/…
Іван Черних

1
Дякую. просто .catch (err => err) щоб після. then () працював у мене. =)
Нобі Фудзіока,

Відповіді:


56

функція catch у вашому api повинна або повернути деякі дані, які можуть бути оброблені викликом Api у класі React, або викинути нову помилку, яку слід вловити за допомогою функції catch у коді вашого класу React. Останній підхід повинен бути приблизно таким:

return fetch(url)
.then(function(response){
  return response.json();
})
.then(function(json){
  return {
    city: json.name,
    temperature: kelvinToF(json.main.temp),
    description: _.capitalize(json.weather[0].description)
  }
})
.catch(function(error) {
console.log('There has been a problem with your fetch operation: ' + error.message);
 // ADD THIS THROW error
  throw error;
});

Тоді у вашому класі React:

Api(region.latitude, region.longitude)
  .then((data) => {
    console.log(data);
    this.setState(data);
  }).catch((error)=>{
     console.log("Api call error");
     alert(error.message);
  });

1
Дякую, я також додав функцію catch в api, і це не видає помилки. Дивно.
Агент Зебра

1
Ви додали помилку кидка після console.log ('Виникла проблема з операцією отримання:' + error.message); у вашій функції вилучення вибору. Див. Помилку кидка, додану у першому фрагменті.
while1

Ах, боже, пропустив це, дякую. помилка в тому Network request failed, що є тією ж помилкою, яку я отримував спочатку. Хм ... все ще не впевнений, що тут відбувається.
Агент Зебра

Будь-яка ідея, чому я все ще отримую повідомлення про Network request failedпомилку?
Агент Зебра

1
Я думаю, що проблема полягає у вашому запиті на URL-адресу. Не в реакції naitve будь-де. Спробуйте відкрити URL-адресу API у сафарі симулятора, щоб переконатися, що симулятор може отримати доступ до URL-адреси. Також переконайтеся, що ваша транспортна політика програми дозволяє дзвінок http. див. stackoverflow.com/questions/31254725/… про це.
while1

3

Ви повинні додати catch () до кінця дзвінка Api. Коли ваш код потрапляє у catch (), він нічого не повертає, тому дані не визначені при спробі використовувати setState () на ньому. Повідомлення про помилку насправді повідомляє вам і це :)


Дякую, я також додав функцію catch в api, і це не видає помилки. Дивно.
Агент Зебра

Що стосується помилки помилки мережі ... ви запускаєте вибірку всередині емулятора? Можливо, він не може отримати доступ до мережі через брандмауер на локальній машині розробника? Або, можливо, android dns не може вирішити URL-адресу - так що спробуйте вказати ip-адресу.
hasseio

Так, запуск його в симуляторі ios, брандмауера немає. Як спробувати з ip-адресою?
Агент Зебра,

Edit: шкода тільки бачив вимога Іос ... спробувати цей відповідь - stackoverflow.com/questions/13542706 / ...
hasseio

Ей, немає проблем, дякую. Я спробував це, не допомогло :(
Агент Зебра

3

Згідно з цим постом , ви повинні включити його в XCode.

  1. Клацніть на свій проект у Навігаторі проектів
  2. Відкрийте вкладку Інформація
  3. Клацніть на стрілку вниз ліворуч до "Налаштування безпеки транспорту додатків"
  4. Клацніть правою кнопкою миші на "Налаштування безпеки транспорту додатків" і виберіть Додати рядок
  5. Для створеного рядка встановіть клавішу “Дозволити довільні навантаження”, введіть логічне значення та значення YES.

введіть тут опис зображення


3

Додавши сюди свій досвід, який, сподіваюся, може комусь допомогти.

Я стикався з тією ж проблемою на емуляторі Android у Linux із гарячим перезавантаженням. Код був правильним відповідно до прийнятої відповіді, і емулятор міг зв’язатися з Інтернетом (мені знадобилося доменне ім’я).

Оновлення програми вручну змусило її працювати. Тож, можливо, це пов’язано з гарячим перезавантаженням.



0

У моєму випадку я запускаю локальний сервер Django в IP 127.0.0.1:8000 із запуском Expo. Просто переконайтеся, що сервер public domainне розміщений на вашому комп'ютері lcoally

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.