Native reagieren: Mögliche Ablehnung von unbehandelten Versprechungen


78

Ich erhalte die folgende Fehlermeldung: Possible unhandled promise rejection (id:0: Network request failed

Hier ist der Versprechen-Code, ich sehe nicht, was hier falsch ist, irgendwelche Ideen?

  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);
    });
}

** Bearbeiten: Ich habe eine Fangfunktion hinzugefügt und einen besseren Fehler erhalten You passed an undefined or null state object; instead, use forceUpdate(). index.ios.js:64 undefined

Hier ist der index.ios.js Code. Die URL ist in Ordnung und gibt mir die richtigen JSON-Daten. Ich kann mit dem Konsolenprotokoll sehen, dass beide region.latitudeund region.longitudein verfügbar sind Api(region.latitude, region.longitude). Ist dataaber undefiniert. Ich bin mir immer noch nicht sicher, was los ist, warum es ein Problem gibt dataund warum es undefiniert ist.

// 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
Fügen Sie .catch()auch hinzu und prüfen Sie, ob der Fehler verschwindet. Referenz: facebook.github.io/react-native/docs/…
Ivan Chernykh

1
Vielen Dank. einfach .catch (err => err) bis nach .then () für mich gearbeitet hat. =)
Noby Fujioka

Antworten:


53

Die catch-Funktion in Ihrer API sollte entweder einige Daten zurückgeben, die vom Api-Aufruf in der React-Klasse verarbeitet werden könnten, oder einen neuen Fehler auslösen, der mithilfe einer catch-Funktion in Ihrem React-Klassencode abgefangen werden sollte. Letzterer Ansatz sollte ungefähr so ​​aussehen:

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;
});

Dann in Ihrer Reaktionsklasse:

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

1
Vielen Dank, ich habe die catch-Funktion auch in der API hinzugefügt und es wird kein Fehler ausgegeben. Seltsam.
Agent Zebra

1
Haben Sie nach console.log einen Wurffehler hinzugefügt ('Es ist ein Problem mit Ihrer Abrufoperation aufgetreten:' + error.message); in Ihrer Fetch-Catch-Funktion. Siehe Wurffehler im ersten Snippet hinzugefügt.
während1

Ah je, das habe ich verpasst, danke. Der Fehler ist Network request failed, das ist der gleiche Fehler, den ich am Anfang bekommen habe. Hmm ... immer noch nicht sicher, was hier los ist.
Agent Zebra

Irgendeine Idee, warum ich immer noch einen Network request failedFehler bekomme ?
Agent Zebra

1
Ich denke, das Problem liegt in Ihrer URL-Anfrage. Nicht in naiv reagieren wo. Versuchen Sie, die API-URL in der Simulatorsafari zu öffnen, um sicherzustellen, dass der Simulator auf die URL zugreifen kann. Stellen Sie außerdem sicher, dass Ihre App-Transportrichtlinie einen http-Anruf zulässt. Siehe dazu stackoverflow.com/questions/31254725/… .
während1

3

Sie sollten den catch () am Ende des Api-Aufrufs hinzufügen. Wenn Ihr Code auf catch () trifft, gibt er nichts zurück, sodass die Daten nicht definiert sind, wenn Sie versuchen, setState () darauf zu verwenden. Die Fehlermeldung sagt dir das auch :)


Vielen Dank, ich habe die catch-Funktion auch in der API hinzugefügt und es wird kein Fehler ausgegeben. Seltsam.
Agent Zebra

In Bezug auf den Netzwerkfehler ... führen Sie den Abruf in einem Emulator aus? Möglicherweise kann es aufgrund einer Firewall auf Ihrem lokalen Entwicklungscomputer nicht auf das Netzwerk zugreifen? Oder vielleicht können die Android-DNS die URL nicht auflösen - versuchen Sie es also mit einer IP-Adresse.
Hassio

Ja, es läuft im iOS-Simulator, keine Firewall. Wie versuche ich es mit einer IP-Adresse?
Agent Zebra

Bearbeiten: Entschuldigung, habe gerade die ios-Anforderung gesehen ... versuchen Sie diese Antwort - stackoverflow.com/questions/13542706/…
hatio

Hey kein Problem, danke. Ich habe es versucht, habe nicht geholfen :(
Agent Zebra

3

Laut diesem Beitrag sollten Sie es in XCode aktivieren.

  1. Klicken Sie im Projektnavigator auf Ihr Projekt
  2. Öffnen Sie die Registerkarte Info
  3. Klicken Sie auf den Abwärtspfeil links neben "App Transport Security Settings".
  4. Klicken Sie mit der rechten Maustaste auf "Sicherheitseinstellungen für den App-Transport" und wählen Sie Zeile hinzufügen
  5. Setzen Sie für die erstellte Zeile den Schlüssel „Allow Arbitrary Loads“, lassen Sie boolean und den Wert YES ein.

Geben Sie hier die Bildbeschreibung ein


3

Fügen Sie hier meine Erfahrung hinzu, die hoffentlich jemandem helfen könnte.

Ich hatte das gleiche Problem mit dem Android-Emulator unter Linux beim Hot-Reload. Der Code war gemäß der akzeptierten Antwort korrekt und der Emulator konnte das Internet erreichen (ich brauchte einen Domainnamen).

Durch manuelles Aktualisieren der App funktionierte sie. Vielleicht hat es etwas mit dem heißen Nachladen zu tun.



0

In meinem Fall verwende ich ein lokales Django-Backend in IP 127.0.0.1:8000 mit Expo-Start. public domainStellen Sie einfach sicher, dass der Server nicht lokal auf Ihrem Computer gehostet ist

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.