How to wait for evaluating values in React from nested requests?

[亡魂溺海] 提交于 2020-08-09 08:15:54

问题


I faced with problem that React didnt wait evalating values. I have about 10 GET requests in useEffect and then placing it on hook state:

const [data,setData]=useState()
    useEffect(async()=>{
     //here axios requests
     setData('here retrieved data above');
    },[]);

I wrapped in async function but it not helping and my react code starting without data from axios requests, but at console i see data from every request with mark "value below was evaluated just now". How I can wait for evaluating? As I understand it related with mutating objects - https://www.freecodecamp.org/news/mutating-objects-what-will-be-logged-in-the-console-ffb24e241e07/ But didnt understand how to solve it

My code:

const SmallGrid = (props)=>{
    return <div>
            <h1>{props.name}</h1>
            {props.elements && props.elements.map((el, idx)=>{
                return <Link to={`${el.url.split("http://swapi.dev/api")[1].slice(0, -1)}`} className={styles.links}>{el.name}</Link>
            })}
          </div> 
};

function UniPage({match}) {
    const[data, setData] = useState({});
const getData = async () => {
    try {
        const firstData = await axios.get(`https://swapi.dev/api${match.url}`);
        console.log(firstData.data);
        let addData = {};
        await Promise.all(
            Object.keys(firstData.data).map((key)=>{
                if(Array.isArray(firstData.data[key])){
                    let tempArray = [];
                    firstData.data[key].map((url)=>{
                        axios.get(url)
                        .then((data)=>{
                            tempArray.push(data.data)
                        })
                    });
                    addData[key] = tempArray;
                }
            })
        ).then(result=>{
            console.log(addData);
            setData(Object.assign(firstData.data,addData));
        })
    } catch (err ) {
        // errors
        console.log(err,"connection error")
    }
}

useEffect(() => {
    getData()
}, []);

With this code I missing part of data from nested requests and getting it in console like evaluated value.


回答1:


Unfortunately, useEffect cannot be made to wait for promises to resolve. This is because, in React, the effect hook expects the value returned by the function that is passed to it to be a cleanup function. Therefore, handing an async function to it will result in the returned Promise being interpreted as such.

A typical workaround is to use Promise.prototype.then() (outlined below as Strategy A).

Another solution is to shift all async logic into separate functions that can be made to wait (outlined below as Strategy B). This tends to be the preferred as it allows for the opportunity to insinuate what is happening via the name of the function and leads to neater code.

See below for a practical example.

// State.
const [data, setData] = useState()

// Did Mount.
useEffect(() => {
  
  // Strategy A.
  axios.get('/endpoint').then(response => setData(response.data))

  // Strategy B.
  const fetchData = async () => {
    const {data} = await axios.get('/endpoint')
    setData(data)
  }
  fetchData()

}, [])


来源:https://stackoverflow.com/questions/63125026/how-to-wait-for-evaluating-values-in-react-from-nested-requests

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