提前退出useEffect挂钩,导致“错误:重新渲染过多”

时间:2020-01-04 09:19:38

标签: javascript reactjs react-hooks use-effect

我有一个react自定义钩子,需要从中退出,这是我的代码

export const useGetData = (url) => {
  const [state, setState] = useState([]);

  let isNew = true;
  let dtFromC = [];
  dtFromC = useRetrieve(key);
  if (dtFromC.length > 0) {
    setState({
      dtFromC
    });
    isNew = false;
  }

  useEffect(() => {
      if (isNew) {
        fetch(url, {
          method: 'Post',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(body)
        }).then(response => response.json())
        setState({
          response
        });
      ).catch(error =>
        console.error('Error:', error)
      );
    }
  }, [url]);

  return state;
}

在上面的代码中,useRetrieve(key)是另一个自定义钩子,它被调用并返回一个数组,在检查数组是否不为空时,我想更新状态并使isNew = false如此,下代码不应执行,但会给我上述错误。我的代码有什么问题,我该如何纠正?

1 个答案:

答案 0 :(得分:2)

您已经创建了一个无限循环:

dtFromC = useRetrieve(key); // you get dtFromC
if (dtFromC.length > 0) { // it's length is greater than 0
  setState({ dtFromC }); // you set the state which causes a rerender, and you start the loop again
  isNew = false;
}

您应将处理从dtFromC移至useEffect,以检查是否有任何更改。如果dtFromC发生更改,它将检查是否需要更新状态(length > 0)或进行提取调用。

示例(未经测试):

export const useGetData = (url) => {
  const [state, setState] = useState([]);
  const dtFromC = useRetrieve(key);

  useEffect(() => {
    if (dtFromC.length > 0) {
      setState({ dtFromC });
    } else {
      fetch(url, {
          method: 'Post',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(body)
        })
        .then(response => response.json())
        .then(response => setState({ response }))
        .catch(error => console.error('Error:', error));
    }
  }, [url, dtFromC, setState]);

  return state;
}