使用获取更新状态,然后在useEffect中使用状态不起作用

时间:2020-02-13 14:31:26

标签: javascript reactjs react-hooks setstate

我在React中有一个组件,在useEffect中,我进行了两个API调用并设置了两个状态。仍然停留在useEffect之后,我试图用API更新的状态之一设置另一个状态。如果通过将useEffect的方括号参数保持为空来执行此操作,则不会设置状态。如果我在括号中传递状态常量,则会陷入无限循环。

async function fetchData() {
    const agentRes = await fetch("http://localhost:3004/agentsdata");
        agentRes
            .json()
            .then(res => setAgents(res))
            .catch(err => console.log(err));

    const queueRes = await fetch("http://localhost:3004/queuedata");
        queueRes
            .json()
            .then(res => setBaseQueues(res))
            .catch(err => console.log(err));
    }

useEffect(() => {

    fetchData();

    let pge;

    if (props.location.data !== undefined) {
        pge = props.location.data.page;
    }
    else {pge = 1;}

    setUser(props.match.params.user);
    setPage(pge);


    let lowerB = (0 +((pge - 1) * 10));
    let upperB = 10 + ((pge - 1) * 10);

    setQueues(baseQueues.slice(lowerB, upperB)); // here the state is not getting set.
}, [queues])

如何做到这一点,以便可以根据需要在useEffect中进行设置。

3 个答案:

答案 0 :(得分:2)

useEffect(() => {
  const doAsyncStuff = async () => {
     await fetchData(); // wait for this data to load
     const { data } = props.location;
     let pge = data !== undefined ? data.page : 1;
     setUser(props.match.params.user);
     setPage(pge);
     
     let lowerB = (0 +((pge - 1) * 10));
     let upperB = 10 + ((pge - 1) * 10);
     
     setQueues(state => state.slice(lowerB, upperB)); // change here
  }
  doAsyncStuff();
}, [queues])

首先,我认为您需要等待数据加载,因此必须等待await fetchData();

然后在设置setQueues时必须执行setQueues(state => state.slice(lowerB, upperB));

答案 1 :(得分:0)

您可以使用更简单的化学方法:

useEffect(() => {
  fetchData();
}, [queues])

useEffect(() => {
  let pge;

  if (props.location.data !== undefined) {
      pge = props.location.data.page;
  }
  else {pge = 1;}

  setUser(props.match.params.user);
  setPage(pge);

  let lowerB = (0 +((pge - 1) * 10));
  let upperB = 10 + ((pge - 1) * 10);

  setQueues(baseQueues.slice(lowerB, upperB)); // here baseQueues is updated.
}, [baseQueues])

... ,但您可能不需要其中的大部分

  • queues是派生数据;
  • 可以在页面属性更改后的每个渲染上“计算”此子集;
  • 获取页面参数后可能超出范围-重定向?

答案 2 :(得分:0)

我已尝试修复代码,并在注释中给出了有关如何正确使用useEffect钩子的详细说明。我强烈建议您阅读Dan Abramov的this blog post,它将清除您对使用useEffect钩子的大部分误解

//since you data fetching code does not depend on anything inside your component you can hoist it outside the component.

async function getAgentData(){
  try{
     const response = await fetch('http://localhost:3004/agentsdata');
     return await response.json();
  } catch(error){
    console.log(error)
  }
}

async function getQueueData{
  try{
     const response = await fetch('http://localhost:3004/queuedata');
     return await response.json();
  } catch(error){
    console.log(error)
  }
}


function YourComponent(props){

   // destructure your props
   const { location: { data }, match } = props;
   const { params: { user } } = props.match;

   // Split your hooks by concern keep the related code together
   useEffect(() => {

      setUser(user);

   // add ALL you dependencies for this effect
   }, [user])

   // Second Effect
   useEffect(() => {

     const pge = (data == undefined)? 1 : data.page;
     const lowerB = (0 +((pge - 1) * 10));
     const upperB = 10 + ((pge - 1) * 10);

     setPage(pge);

     async function fetchData(){
       const agentRes = await getAgentData();
       setAgents(agentRes);

       const queueRes = await getQueueData();

       // Note: There need to first save it to state; then retrieve then slice then update again. When all you need is this
       setBaseQueues(queueRes.slice(lowerB, upperB));
     }

     //call the function here
     fetchData();

     //Add the ALL the dependencies of this effect i.e all props, functions, state variables inside 
     //YourComponent that you have used in this effect
     //In this case this effect is only run when this.props.location.data is changes, which is the desired behaviour
   }, [ data ])

   return <>Whatever</>
}

相关问题