Повторный вызов useEffect после неудачного запроса на загрузку API. - PullRequest
0 голосов
/ 26 марта 2020

Я выполняю useEffect (), чтобы обновить состояние с данными JSON. Однако запрос на выборку иногда терпит неудачу, поэтому я хочу повторно выполнить ловушку useEffect, если это произойдет:

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

Вот функция getJsonData () на всякий случай:

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.
  }
}

Ответы [ 2 ]

1 голос
/ 26 марта 2020

Это будет работать

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>
    );
}
1 голос
/ 26 марта 2020
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;
...