React觀察日記-useState

React觀察日記-useState

觀察到的 USESTATE 觸發機制

  • 元件自己 setState
  • 父元件 setState
  • 父元件 state 用 props 傳給子元件 setState
  • 一次寫多個 setState

 

元件自己 setState

  • 如果前後 state 不一樣觸發重新 render
    • state 不一樣的定義
      • 如果是 Reference type 的資料類型,只要參照一樣就算裡面的值更新還是一樣的 state
        * 如果是Reference type 的資料類型,修改同一個參照後 setState 不會觸發 render,但下次如果有同個元件的 state 更新觸發 rerender,剛剛修改同一個參照的資料也會更新
    • 如果是 Primitive type 的資料類型,只要值不一樣就算
  • 重新 render 只會在自己這個元件,不會觸發其他元件 render

父元件 setState

  • setState 之後
    • 父元件更新
      • 父元件更新會觸發所有子元件 rerender
      • 父元件 setState 如果沒有觸發重新 render,子元件也不會重新 render

父元件 state 用 props 傳給子元件 setState

  • 子元件 setState 之後
    • 父元件更新
      • 同父元件 setState
      • 需要注意如果傳的 props 是 Reference type
        • 子元件如果只有更新值,沒有更新 Reference,畫面不會更新,要等到下次這個子元件重新render之後,子元件更新後的 props 才會顯示到畫面上,而且父元件的 state還是會是舊的,畫面上也是舊的,因為並沒有觸發父元件重新render

父元件 state 用 props 傳給子元件 setState

    const [conterA, setCounter] = useState(0);
    const pendingTripleAdd = (): void => {
      setCounter(conterA + 1);
      setCounter(conterA + 1);
      setCounter(conterA + 1);
    };
  • 上面的 setState 只會觸發一次,所以結果會是 conterA === 1
  • 下面的 setState 會觸發三次,所以結果會是 conterA === 3
    const [conterA, setCounter] = useState(0);
      const pendingTripleAdd = (): void => {
      setCounter((conterA) => conterA + 1);
      setCounter((conterA) => conterA + 1);
      setCounter((conterA) => conterA + 1);
    };

關於官網總結

  1. setState 會要求新的渲染
  2. React將狀態存儲在組件外部,就像放在一個架子上
  3. 當您呼叫useState時,React會給您該渲染的狀態快照
  4. 變量和事件處理程序不會“存活”於重新渲染中。每次渲染都有自己的事件處理程序
  5. 每次渲染(及其中的函數)都會始終“看到”React給該渲染的狀態快照
  6. 您可以在事件處理程序中進行心理上的替換狀態,就像您思考呈現的JSX一樣
  7. 過去創建的事件處理程序具有它們所創建的渲染中的狀態值

排隊 (Queueing) 一系列的狀態更新

設置狀態不會改變現有渲染中的變量,而是要求一個新的渲染。
React在事件處理程序完成運行之後處理狀態更新。這就是所謂的批次處理。 要在一個事件中多次更新某個狀態,可以使用setNumber(n => n + 1)更新器功能。

個人總結

react 元件渲染其實就是 呼叫 render(class 元件) function (函式型元件),當下會產生類似 snapShot 的動作(不確定與 virturl dom 的關係),下次有 event 觸發 setState 時,會觸發batch 批處理(react 對於多個setState的優化,類似將 state 更新動作放到一個 queue 裡,最後算出更新的 值 才是真正拿去更新state ),React 不會在多個有意義的事件(例如點擊)之間進行批處理,每個點擊都會單獨處理。
請放心,React 只在通常情況下安全時才進行批處理。這確保了,例如,如果第一次按鈕點擊禁用了表單,第二次點擊不會再次提交它。

更新state後會再次觸發 render 導致元件更新,創造新的snapShot,當snapShot 與前次比較有差異,則會在commit階段實際更新有差異的 DOM。

感謝閱讀,如果有錯誤或是講得不清楚的部分,再請留言指教

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *