React hooks fetch 不会停止获取

React hooks fetch won't stop fetching

我正在尝试重建一些 class 组件作为功能组件,使用 React 挂钩来执行获取。

我可以获取数据,这很好,但它每隔几毫秒就会调用我的 API,我只希望它获取数据并像在 class 中那样停止组件与 componentDidMount.

我想我明白它为什么这样做了(函数内的 fetchData() 意味着它会一直调用自己)但我不确定如何修复它。

我尝试添加一个 setInterval,更改顺序,并将 fetchData() 移到函数外部(该组件不会呈现,因为它当时未定义)。

const MyFunction = () => {

const [apiResponse,setApiResponse] = useState({})

  async function fetchData() {

    const res = await fetch(`http://localhost:9000/example`,{
      method: 'POST',
      mode: 'cors',
      body: JSON.stringify({date: '20190707'}),
      headers: {'content-type': 'application/json',
      credentials: 'include'
    }
    })
  res
  .json()
  .then(res => setApiResponse(res))
  }

useEffect(() => {

  fetchData();

});


var queryResult = apiResponse['units']


return (
  <React.Fragment>  
    <CardHeader color={"info"} stats icon>
    <CardIcon color={"info"}>
    <Icon>{"trending_up"}</Icon>
    </CardIcon>
    <p className={''}>Drop In</p>
      <h3 className={''}>
        {queryResult} <small>Units</small>
      </h3>
    </CardHeader>
    <CardFooter ></CardFooter>
  </React.Fragment>        
);

}

尝试在 useEffect 的末尾添加一个空数组:

useEffect(() => {

  fetchData();

}, []);

React 文档:https://reactjs.org/docs/hooks-effect.html

Note

If you use this optimization, make sure the array includes all values from the component scope (such as props and state) that change over time and that are used by the effect. Otherwise, your code will reference stale values from previous renders. Learn more about how to deal with functions and what to do when the array changes too often.

If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ([]) as a second argument. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to re-run. This isn’t handled as a special case — it follows directly from how the dependencies array always works.

If you pass an empty array ([]), the props and state inside the effect will always have their initial values. While passing [] as the second argument is closer to the familiar componentDidMount and componentWillUnmount mental model, there are usually better solutions to avoid re-running effects too often. Also, don’t forget that React defers running useEffect until after the browser has painted, so doing extra work is less of a problem.

We recommend using the exhaustive-deps rule as part of our eslint-plugin-react-hooks package. It warns when dependencies are specified incorrectly and suggests a fix.

你所做的很好 - 你只需要将一个空的依赖数组添加到你的 useEffect 实现(下面的解释),就像这样 -

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

当您将一个数组传递给 useEffect 时,您实际上是在告诉 React 仅 运行 如果数组中的一个值发生变化,您的效果。

我们使用一个空数组作为依赖数组,因为它会产生效果来模拟 Class 组件中众所周知和喜爱的 ComponentDidMount 生命周期事件,运行ning仅在组件安装时而不是在每次渲染之后。

您可以使用 useEffect 来模拟其他生命周期事件,例如 ComponentWillUnmountComponentDidUpdate 等。我建议阅读 [=] 中有关 useEffect 挂钩的更多信息17=].