简体   繁体   English

反应 useEffect 钩子导致无限循环

[英]React useEffect hook is causing infinite loop

I have an useState hook on my component, it looks like this:我的组件上有一个 useState 挂钩,它看起来像这样:

const [scoutMode, setScoutMode] = useState("camp");
const [bottomLinks, setBottomLinks] = useState([]);
useEffect(() => {
if (scoutMode == "weeklyProgramme") {
  setBottomLinks([
    {
      name: "Tasks",
      link: "/tasks"
  },
  {
    name: "Checklists",
    link: "/checklists"
  }
  
  ])
} else if (scoutMode == "camp") {
  setBottomLinks([
    {
      name: "Tasks",
      link: "/tasks"
  },
  {
    name: "Map",
    link: "/map"
  }
  ])
} else {
  setBottomLinks([]);
}
console.log(bottomLinks);
})

But bottomLinks is printend on console continuously, I have an infinite loop.但是bottomLinks在控制台上连续打印,我有一个无限循环。 I remember there was a rule that useState must never be called inside useEffect, am I wrong, or could someone explain what is happening in my code?我记得有一条规则永远不能在 useEffect 中调用 useState,我错了,或者有人可以解释我的代码中发生了什么吗?

PROBLEM:问题:

When you modify a component's state within useEffect hook, the component will rerender causing the useEffect to be called again;当您在 useEffect 挂钩中修改组件的 state 时,该组件将重新渲染,导致再次调用 useEffect; thus entering into an infinite loop.从而进入无限循环。 That's why you should add a dependency array as a second argument to useEffect to invoke the function when dependencies change.这就是为什么你应该添加一个依赖数组作为 useEffect 的第二个参数,以便在依赖关系发生变化时调用 function。

SOLUTION:解决方案:

Add a dependency array like so:添加一个依赖数组,如下所示:

const [scoutMode, setScoutMode] = useState("camp");
const [bottomLinks, setBottomLinks] = useState([]);
useEffect(() => {
if (scoutMode == "weeklyProgramme") {
  setBottomLinks([
    {
      name: "Tasks",
      link: "/tasks"
  },
  {
    name: "Checklists",
    link: "/checklists"
  }
  
  ])
} else if (scoutMode == "camp") {
  setBottomLinks([
    {
      name: "Tasks",
      link: "/tasks"
  },
  {
    name: "Map",
    link: "/map"
  }
  ])
} else {
  setBottomLinks([]);
}
console.log(bottomLinks);
}, [scoutMode])

you must use dependencies to useEffect function know whether rerender or not, typically syntax as您必须使用依赖项来使用效果 function 知道是否重新渲染,通常语法为

useEffect(() => {
  // code
}, [denpendencies])

In your case, if you just only it's run once, you must put dependencies by [].在您的情况下,如果您只运行一次,则必须通过 [] 放置依赖项。 Otherwise, if you want useEffect run each scoutMode change, you put dependencies by [scoutMode]否则,如果您希望 useEffect 运行每个scoutMode更改,您可以通过 [scoutMode] 放置依赖项

  1. It first works when rendering occurs.它首先在渲染发生时起作用。 useEffect(() => {... }, []) useEffect(() => {... }, [])

  2. It works whenever the state of scoutMode changes useEffect(() => {... }, [scoutMode])只要 scoutMode 的 state 更改 useEffect(() => {... }, [scoutMode])

useEffect lets you perform side effects in function components. useEffect允许您在 function 组件中执行副作用。 As your useEffect has state dependency( scoutMode ) and based on this, your changing the state( bottomLinks ) inside useEffect , which will cause re-render and useEffect will be called again, this goes on.由于您的 useEffect 具有 state 依赖项( scoutMode ),并且基于此,您更改了useEffect内部的状态( bottomLinks ),这将导致重新渲染,并且将再次调用useEffect ,这样继续下去。 That's why your seeing infinite loop.这就是你看到无限循环的原因。 You need tell when to run the useEffect hook by adding dependancies.您需要通过添加依赖项来确定何时运行useEffect挂钩。

In your case, you can tell useEffect to run whenever scoutMode changes by adding hook dependancy.在您的情况下,您可以通过添加挂钩依赖项来告诉 useEffect 在scoutMode更改时运行。

useEffect(() => {
 // your stuff
}, [scoutMode])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM