P粉9869374572023-08-25 13:15:08
最近我遇到了這個需求。例如,假設你有一個元件,它會填滿一個數組,並且能夠根據使用者的某些操作(例如在我的情況下,當使用者不斷向下滾動螢幕時,我會每次載入10個項目的動態來源。程式碼看起來有點像這樣:
function Stream() { const [feedItems, setFeedItems] = useState([]); const { fetching, error, data, run } = useQuery(SOME_QUERY, vars); useEffect(() => { if (data) { setFeedItems([...feedItems, ...data.items]); } }, [data]); // <---- 这违反了hooks的规则,缺少了feedItems ... <button onClick={()=>run()}>获取更多</button> ...
顯然,你不能簡單地將feedItems加入到useEffect鉤子的依賴清單中,因為你在其中呼叫了setFeedItems,所以會陷入循環。
函數式更新來拯救:
useEffect(() => { if (data) { setFeedItems(prevItems => [...prevItems, ...data.items]); } }, [data]); // <--- 现在一切都好了
P粉2383558602023-08-25 00:00:10
在React中,狀態更新是異步的。因此,在下次更新時,count
中可能會有舊值。例如,比較以下兩個程式碼範例的結果:
function Counter({initialCount}) { const [count, setCount] = useState(initialCount); return ( <> Count: {count} <button onClick={() => setCount(initialCount)}>重置</button> <button onClick={() => { setCount(prevCount => prevCount + 1); setCount(prevCount => prevCount + 1)} }>+</button> </> ); }
和
function Counter({initialCount}) { const [count, setCount] = useState(initialCount); return ( <> Count: {count} <button onClick={() => setCount(initialCount)}>重置</button> <button onClick={() => { setCount(count + 1); setCount(count + 1)} }>+</button> </> ); }