Search code examples
react-nativereact-hookses6-promise

useEffect returns unhandled promise


I have been for several hours trying to get an API to be called in ReactNative useEffect hook. Sometimes when I restart my app the value is resolved. But most of the time, I have an Unhandled promise rejection. I googled and tried various methods. I tried using .then etc.. I just can't figure it out.

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;

Solution

  • I think my issue was not just promise, the issue is also seems to be me not handling undefined/null in the state. The below code is working for me.

    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;
    

    Note: I am setting the state in useEffect as well as in the request. I am yet to check if I can just do it once.