我有一个组件,用于维护随时间推移获取的项目的列表。该组件在加载时获取项目,并且还可以由于用户交互而获取新项目。每当获取项目时,都应将其添加到项目列表中。以下代码进行无限递归,因为每次我将新项目添加到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
}
如何使用Hooks实现此目的?
答案 0 :(得分:1)
您可以使用以当前状态作为参数的函数来更新状态。这样,您就不需要items
作为依赖项。
setItems((currentState) => currentState.concat(item));
// is the same as
setItems([items].concat(item));
旁注:您也不需要在依赖项数组中添加setItems
,省去了。
答案 1 :(得分:0)
约functional updates
中useState
的TIL
为此替换了有问题的useEffect
呼叫
useEffect(() => {
setItems(items => items.concat([item]))
}, [item, setItems])