搜尋

首頁  >  問答  >  主體

為何使用React中的useState和函數式更新表單是必要的?

<p>我正在閱讀有關React Hook函數更新的文檔,並看到了這句話:</p> <blockquote> <p>“ ”和“-”按鈕使用函數形式,因為更新的值是基於先前的值</p> </blockquote> <p>但我看不出函數更新的目的是什麼,以及它們與直接在計算新狀態時使用舊狀態之間的差異。 </p> <p><strong>為什麼React useState Hook的更新函式需要函式更新形式? </strong> <strong>有哪些例子可以清楚看到差異(因此使用直接更新會導致錯誤)? </strong></p> <p>例如,如果我將文件中的範例更改為:</p> <pre class="brush:php;toolbar:false;">function Counter({initialCount}) { const [count, setCount] = useState(initialCount); return ( <> Count: {count} <button onClick={() => setCount(initialCount)}>Reset</button> <button onClick={() => setCount(prevCount => prevCount 1)}> </button> <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button> </> ); }</pre> <p>直接更新<code>count</code>:</p> <pre class="brush:php;toolbar:false;">function Counter({initialCount}) { const [count, setCount] = useState(initialCount); return ( <> Count: {count} <button onClick={() => setCount(initialCount)}>Reset</button> <button onClick={() => setCount(count 1)}> </button> <button onClick={() => setCount(count - 1)}>-</button> </> ); }</pre> <p>我看不出任何行為上的差異,也無法想像出count不會被更新的情況(或不是最新的情況)。因為每當count發生變化時,都會呼叫新的閉包來捕獲最新的count。 </p>
P粉041856955P粉041856955487 天前528

全部回覆(2)我來回復

  • P粉986937457

    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]);     //  <--- 现在一切都好了

    回覆
    0
  • P粉238355860

    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>
        </>
      );
    }

    回覆
    0
  • 取消回覆