当参数默认为数组时,反应无限循环useEffect

React Infinite loop useEffect when a parameter has an array as default

以前我从来没有发生过,我也不知道为什么会这样。

我有这两个组件在子组件的 useEffect 中创建无限循环:

function Container(){
  return <div> <Description /> </div>
}

// If I remove "= []" part no infinite loop is created
function Description({list = []}){
  const [dict, setDict] = useState({})

  useEffect(() => {
      console.log('this is for the inifinite loop log')
      setDict({}) // also, If a remove this line no infinite loop is created
  }, [list]) 

  return <div>something...</div>
}

** 已编辑:这段代码只是我的问题的简化 **

我知道默认数组是在每次重新渲染组件时使用不同的内存指针创建的,但是没有办法将列表作为默认道具并同时将其用作 useEffect参数?

这很可能是因为 list 数组在内存中不是同一个对象,并且每次渲染都会创建新数组。

如果您的 setDict 中有默认 {},则无需在 useEffect 中重新分配它。

这也可能是因为您没有通过 Description 组件在 Container 函数中将 list 作为道具传递。如果您通过该道具,您也应该以这种方式缓解无限循环。

当React的函数组件状态发生变化时,会再次调用该函数。而当函数组件的状态发生变化时,如果useEffect的依赖数组也发生变化,则调用useEffect中的回调。

上面代码中调用setDict时,每次都会创建一个新的数组实例,也就是默认放入list中的值,所以useEffect更新回调继续调用

因此您可以使用相同的实例数组来使用空数组作为默认值。

const emptyArray = [];
// If I remove "= []" part no infinite loop is created
function Description({list = emptyArray}){
  const [dict, setDict] = useState({})

  useEffect(() => {
      console.log('this is for the inifinite loop log')
      setDict({}) // also, If a remove this line no infinite loop is created
  }, [list]) 

  return <div>something...</div>
}

光看上面的示例代码,我不知道你想要的最终目的是什么。我认为您的代码通过处理来自父组件的 list 来创建 setDict 的参数。一般来说,我认为 Description 的父级只将数组或空数组值发送到 list 道具。如果是这样,我认为这是在不支持空数组的情况下不支持空数组时导致错误的更好方法,这是 list.

的默认值