【问题标题】:useEffect returns unhandled promiseuseEffect 返回未处理的承诺
【发布时间】:2020-02-28 02:06:47
【问题描述】:

我已经花了几个小时试图在 ReactNative useEffect 钩子中调用 API。有时当我重新启动我的应用程序时,该值已解决。但大多数时候,我有一个Unhandled promise rejection。我用谷歌搜索并尝试了各种方法。我尝试使用.then 等。我就是想不通。

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;

【问题讨论】:

  • jsonServer 正在返回一个承诺。你在处理吗?
  • 尝试简化您的代码以对其进行调试,将调用 jsonServer.get 移动到 setToState 并将主体包装在 try catch 中并将 id 添加到 useEffect 的依赖数组中以避免重新渲染中的额外调用

标签: react-native react-hooks es6-promise use-effect


【解决方案1】:

你可以这样做:

....
....

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)
   }
  },[]);

我相信这将解决您的未处理承诺拒绝错误。如果仍然不能解决问题,请尝试在 Sanck 中创建相同的问题。

【讨论】:

    【解决方案2】:

    我认为我的问题不只是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 以及请求中设置状态。我还没有检查我是否可以只做一次。

    【讨论】:

    • async 函数总是返回一个 Promise。 return result; 行将使用值 result 解析 Promise。仍然需要等待承诺或.then'd。
    • @RossAllen 感谢您的提示。我能够更新我的代码以供使用。
    • catch 块呢?如果承诺被拒绝怎么办?
    • @pratap 我的最终代码版本有错误处理。但是,这解决了我在原始问题中指出的问题。我将尝试发布更新的代码。谢谢
    猜你喜欢
    • 1970-01-01
    • 2021-07-22
    • 2020-12-20
    • 1970-01-01
    • 2014-10-29
    • 2020-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多