Re-calling useEffect after a failed api fetching request

谁说胖子不能爱 提交于 2020-04-17 20:38:13

问题


I am executing useEffect() to update a state with JSON data. However the fetch request sometimes fails, so I want to re-execute the useEffect hook if that happens:

...
import React, {useState, useEffect} from 'react';
import {getJsonData} from './getJsonData';

const myApp = () => {
    var ErrorFetchedChecker = false;
    const [isLoading,setIsLoading] = useState(true);
    const [data,setData] = useState(null);

    const updateState = jsonData => {
      setIsloading(false);
      setData(jsonData);
    };

    useEffect(() => {
      //console.log('EXECUTING');
      getJsonData().then(
        data => updateState(data),
        error => {
          Alert.alert('DATA FETCHING ERROR !', 'Refreshing ?...');
          ErrorFetchedChecker = !ErrorFetchedChecker;
          //console.log('LOG__FROM_CountriesTable: Executed');
        },
      );
    }, [ErrorFetchedChecker]);//Shouldn't the change on this variable
                              //be enough to re-execute the hook ? 

    return (
      <View>
        <Text>{state.data.title}</Text>
        <Text>{data.data.completed}</Text>
      </View>
    );
}

Here's the getJsonData() function just in case:

export async function getJsonData() {
  try {
    let response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
    let responseJson = await response.json();
    return responseJson;
  } catch (error) {
    throw error;
    // Also, is this the correct way to handle the error ?
    // As the Alert in useEffect goes off either ways.
    // If not, advise me on how the error should be handled.
  }
}

回答1:


This will work

const myApp = () => {
    const [errorFetchedChecker, setErrorFetchedChecker] = useState(false);
    const [isLoading,setIsLoading] = useState(true);
    const [data,setData] = useState(null);

    const updateState = jsonData => {
      setIsloading(false);
      setData(jsonData);
    };

    useEffect(() => {
      //console.log('EXECUTING');
      getJsonData().then(
        data => updateState(data),
        error => {
          Alert.alert('DATA FETCHING ERROR !', 'Refreshing ?...');
          setErrorFetchedChecker(c => !c);
          //console.log('LOG__FROM_CountriesTable: Executed');
        },
      );
    }, [errorFetchedChecker]);

    return (
      <View>
        <Text>{state.data.title}</Text>
        <Text>{data.data.completed}</Text>
      </View>
    );
}



回答2:


import React, { useState, useRef, useEffect } from "react";
import { Text, View, TextInput } from "react-native";

const App = () => {
  var ErrorFetchedChecker = false;
  const [isLoading, setIsLoading] = useState(true);
  const [data, setData] = useState(null);
  const updateState = (jsonData) => {
    setIsLoading(false);
    setData(jsonData);
  };

  useEffect(() => {
    //console.log('EXECUTING');
    getJsonData()
      .then((data) => {
        console.log("1. Successful, just received the data from our promise");
        updateState(data);
        console.log("2. We set our data because we received it successfully");
        return { alreadySet: true };
      })
      .catch((e) => {
        console.log("1. We failed to gather data in our initial promise");
        console.log("2. Attempting to rerun initial promise");
        return getJsonData();
      })
      .then((data) => {
        if (data.alreadySet) {
          console.log(
            "3. Did not attempt to retry because we are already successful"
          );
        } else {
          console.log("3. Our second attempt succeeded");
          updateState(data);
          console.log("4. Set our data on our second attempt");
        }
      })
      .catch((e) => {
        console.log("3. Both attempts have failed");
      });
  }, []); //Shouldn't the change on this variable
  //be enough to re-execute the hook ?

  return (
    <View>
      <Text>{data ? <Text>{data.title}</Text> : null}</Text>
    </View>
  );
};

export async function getJsonData() {
  try {
    let response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
    let responseJson = await response.json();
    return responseJson;
  } catch (error) {
    throw error;
    // Also, is this the correct way to handle the error ?
    // As the Alert in useEffect goes off either ways.
    // If not, advise me on how the error should be handled.
  }
}
export default App;


来源:https://stackoverflow.com/questions/60872890/re-calling-useeffect-after-a-failed-api-fetching-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!