簡體   English   中英

跟蹤 state 在組件外部使用 promise Hooks React JS 更新

[英]Track that state is updated outside of a component with promise Hooks React JS

我有一個外部 function 通過refImperativeHandler掛鈎更改組件內的 state

const [state, setState] = useState(0);

// inside component
const testFunc = () => {
   setState(1)
}

// outside of component
function *generator {
    yield ...
    yield testFunc()
    // next yield should wait till state is updated, only then it can be executed 
    yield ...
}

但我不知道如何跟蹤 state 已被更改,因為setState掛鈎沒有回調選項。 如何跟蹤 state 在外部 function 中發生變化的時刻,例如我的generator示例?

由於您正在使用鈎子並且更新程序 function 沒有收到像 class 更新程序版本這樣的第二個參數,您可能希望自己實現一個帶有第二個參數的更新程序:

function useStateWithCallback(initState) {
  const cbRef = useRef(null);

  const [state, setState] = useState(initState);

  useEffect(() => {
    if (cbRef.current) {
      cbRef.current(state);
      cbRef.current = null;
    }
  }, [state]);

  const updater = (value, callback) => {
    cbRef.current = typeof callback === "function" ? callback : null;
    setState(value);
  };

  return [state, updater];
}
  • We create our own useState with the same signature, a function that accept an initial state and returns a tuple of the current state and an update function, but this time the updater function takes 2 arguments, the next state and a callback.

  • 我們需要一種方法來存儲傳遞給更新程序的回調,我們可以將它存儲在useState中,但每次更新都會觸發渲染,所以我們將它存儲在一個 ref 中,該 ref 在渲染中是持久的,但可變並且不會觸發重新- 更新時渲染。 我們從null值開始。

  • 我們使用 useState 存儲和處理值的實際useState

  • 我們將效果同步到這個 state 值並調用存儲在我們的參考中的回調。 我們有條件地這樣做,因為效果將在任何 state 更新之前的第一次渲染上運行(這就是我們以null開頭的原因)。

  • 我們創建自己的updater function 將回調存儲在我們的 ref 中(同時驗證它確實是一個函數)並觸發實際的 state 更新。

  • 我們用真正的 state 和我們的自定義更新程序返回我們的元組

運行示例:

 const {useState, useRef, useEffect} = React; function useStateWithCallback(initState) { const cbRef = useRef(null); const [state, setState] = useState(initState); useEffect(() => { if (cbRef.current) { cbRef.current(state); cbRef.current = null; } }, [state]); const updater = (value, callback) => { cbRef.current = typeof callback === "function"? callback: null; setState(value); }; return [state, updater]; } function App() { const [count, setCount] = useStateWithCallback(0); const myCallback = currentState => console.log("currentState", currentState); const onClick = () => { setCount(c => c + 1, myCallback); }; return <button onClick={onClick}>{count}</button>; } const rootElement = document.getElementById("root"); ReactDOM.render( <App />, rootElement );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script> <div id="root" />

您可以為此 promise 創建一個特殊情況:

// inside imperative handle
specialStateSetter: () => {
  // your logic/tracker here
  setState({ value: 0 })
}

因為 setState 沒有回調選項

setState可以傳遞第二個參數,它是在 state 更新后執行的回調 function。

參考: https://fr.reactjs.org/docs/react-component.html#setstate

因為 setState 沒有回調選項我如何跟蹤 state 更改的時刻

你錯了。 setState有回調:

setState(() => ({ value: 0 }), callback)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM