I have a component which maintains a list of items that are fetched over time. The component fetches an item on load, and can also fetch new items as a result of user interaction. Whenever an item is fetched it should be added to the list of items. The following code goes into an infinite recursion, because each time I add a new item to items, the effect is called again with the new items list, and another item is added.
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
}
How can I achieve this using Hooks?