Reactjs 如何避免useEffect钩子中的递归依赖
我有一个组件,它维护一个随时间提取的项目列表。组件在加载时获取一个项目,并且还可以在用户交互的结果中获取新项目。无论何时提取项目,都应将其添加到项目列表中。下面的代码进入无限递归,因为每次我向Reactjs 如何避免useEffect钩子中的递归依赖,reactjs,react-hooks,Reactjs,React Hooks,我有一个组件,它维护一个随时间提取的项目列表。组件在加载时获取一个项目,并且还可以在用户交互的结果中获取新项目。无论何时提取项目,都应将其添加到项目列表中。下面的代码进入无限递归,因为每次我向items添加一个新项时,效果会再次通过新的items列表调用,并添加另一个项 export default function UnintentionallyRecursive () { const [item, setItem] = useState() const [items, setItem
items
添加一个新项时,效果会再次通过新的items
列表调用,并添加另一个项
export default function UnintentionallyRecursive () {
const [item, setItem] = useState()
const [items, setItems] = useState([])
const fetchItem = () => new Promise(resolve => resolve({ title: 'a new item' }))
const updateItem = useCallback(async () => {
const newItem = await fetchItem()
setItem(newItem)
}, [setItem])
useEffect(() => {
updateItem()
}, [updateItem])
// this is the part that causes the recursion
useEffect(() => {
setItems(items.concat([item]))
}, [item, items, setItems])
return null // really UI code which can also call updateItem
}
如何使用钩子实现这一点?您可以使用函数的当前状态作为参数来更新状态。这样,您就不需要将
项作为依赖项
setItems((currentState) => currentState.concat(item));
// is the same as
setItems([items].concat(item));
旁注:您也不需要将setItems
添加到依赖项数组中,它可以保存以省去。您可以使用函数更新状态,并将其当前状态作为参数。这样,您就不需要将项作为依赖项
setItems((currentState) => currentState.concat(item));
// is the same as
setItems([items].concat(item));
旁注:您也不需要将setItems
添加到依赖项数组中,它可以保存以省去。直到中的功能更新
useState
用此函数替换有问题的useffect
调用修复了该问题
useEffect(() => {
setItems(items => items.concat([item]))
}, [item, setItems])
直到useState
用此函数替换有问题的useffect
调用修复了该问题
useEffect(() => {
setItems(items => items.concat([item]))
}, [item, setItems])
比我快30秒:)比我快30秒:)