useEffect возвращает необработанное обещание - PullRequest
1 голос
/ 28 февраля 2020

Я несколько часов пытался заставить API вызываться в перехвате ReactNative useEffect. Иногда, когда я перезагружаю свое приложение, значение разрешается. Но большую часть времени у меня есть Unhandled promise rejection. Я гуглил и пробовал разные методы. Я пытался использовать .then et c .. Я просто не могу понять это.

import React, { useState, useContext, useEffect } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, FlatList } from 'react-native';
import { EvilIcons } from '@expo/vector-icons';
import jsonServer from '../api/jsonServer';


const ShowScreen = ({ navigation }) => {  
  const id = navigation.getParam('id'); 
  const [post, setPost] = useState([]);  

  const getBlog = async () => {
    const result = await jsonServer.get(`http://0.0.0.0/blog/docroot/jsonapi/node/article/${id}`);
    return result;
  }  


  useEffect(() => {

    async function setToState() {
     const val =  await getBlog();
     setPost(val);


    }    

    setToState();    

  },[]);


  return (
    <View>
        <Text>Here {  console.log(post) }</Text>

    </View>
  );
};

ShowScreen.navigationOptions = ({ navigation }) => {
  return {
    headerRight: (
      <TouchableOpacity
        onPress={() =>
          navigation.navigate('Edit', { id: navigation.getParam('id') })
        }
      >
        <EvilIcons name="pencil" size={35} />
      </TouchableOpacity>
    )
  };
};

const styles = StyleSheet.create({});

export default ShowScreen;

Ответы [ 2 ]

1 голос
/ 29 февраля 2020

Я думаю, что моя проблема была не просто promise, проблема также в том, что я не обрабатываю undefined / null в состоянии. Код ниже работает для меня.

import React, { useState, useContext, useEffect } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, FlatList } from 'react-native';
import { EvilIcons } from '@expo/vector-icons';
import jsonServer from '../api/jsonServer';

const ShowScreen = ({ navigation }) => {
  const id = navigation.getParam('id'); 
  const [post, setPost] = useState([]);      

  const getBlog = async () => {
    const result = await jsonServer.get(`http://hello.com/jsonapi/node/article/${id}`).then(
        res => {         
            setPost(res)
            return res;
        }, err => { 
            console.log(err); 
  });        
  }  

  useEffect(() => {  
    setPost(getBlog());             
  },[]);

  return (
    <View>
        <Text>{ post.data ? post.data.data.id : "" }</Text>                        
    </View>
  );
};            

export default ShowScreen;

Примечание: Я устанавливаю состояние как в useEffect, так и в запросе. Мне еще предстоит проверить, смогу ли я сделать это один раз.

1 голос
/ 28 февраля 2020

То, что вы могли бы сделать, выглядит примерно так:

....
....

const [post, setPost] = useState([]); 
const [isMounted, setIsMounted] = useState(false);  

const getBlog = async () => {
    const result = await jsonServer.get(`http://0.0.0.0/blog/docroot/jsonapi/node/article/${id}`);
    return result;
  }  

useEffect(() => {
     setIsMounted(true)
    async function setToState() {
     // using try catch I'm handling any type of rejection from promises. All errors will move to catch block.
      try{
         const val =  await getBlog();
          // checking if component is still mounted. If mounted then setting a value. We shouldn't update state on an unmounted component.
           if(isMounted){
              setPost(val);
           }
         } catch(err){
        console.log("Error", err)
     }
    }    

    setToState();
    return () => {
     // Setting is mounted to false as the component is unmounted.
     setIsMounted(false)
   }
  },[]);

Я считаю, что это решит вашу ошибку отказа от необработанного обещания. Пожалуйста, попробуйте, если это все еще не решит проблему, создаст то же самое в Санке.

...