![](/img/trans.png)
[英]Setting state inside promise and outside promise affects on rendering component in react
[英]Track that state is updated outside of a component with promise Hooks React JS
我有一個外部 function 通過ref
和ImperativeHandler
掛鈎更改組件內的 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.