React useEffect 钩子导致无限循环

时间:2021-01-04 07:05:21

标签: reactjs infinite-loop use-effect use-state

我的组件上有一个 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);
})

但是bottomLinks 是在控制台上连续打印的,我有一个无限循环。我记得有一条规则,永远不能在 useEffect 内部调用 useState,我错了,或者有人可以解释我的代码中发生了什么?

4 个答案:

答案 0 :(得分:3)

问题:

当你在 useEffect 钩子中修改组件的状态时,组件将重新渲染导致再次调用 useEffect;从而进入无限循环。这就是为什么您应该添加一个依赖项数组作为 useEffect 的第二个参数,以便在依赖项发生变化时调用该函数。

解决方案:

像这样添加一个依赖数组:

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])

答案 1 :(得分:0)

你必须使用依赖来使用效果函数知道是否重新渲染,通常语法为

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

在您的情况下,如果您只运行一次,则必须通过 [] 放置依赖项。否则,如果您希望 useEffect 运行每个 scoutMode 更改,则通过 [scoutMode]

放置依赖项

答案 2 :(得分:0)

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

  2. 只要 scoutMode 的状态发生变化,它就会起作用 useEffect(() => { ... }, [scoutMode])

答案 3 :(得分:0)

useEffect 允许您在函数组件中执行副作用。由于您的 useEffect 具有状态依赖 (scoutMode) 并且基于此,您更改 bottomLinks 内的状态 (useEffect),这将导致重新渲染,useEffect 将是再次调用,这样继续。这就是为什么你看到无限循环。您需要通过添加依赖来判断何时运行 useEffect 钩子。

在您的情况下,您可以通过添加钩子依赖来告诉 useEffect 在 scoutMode 发生变化时运行。

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