React Hooks:useCallback中变量/状态声明顺序差异(ES5编译)
关于useCallback中变量/函数声明顺序对其行为影响的疑问
说明:代码会经过Babel编译转换为ES5,所有const和let声明都会被转为var。
场景1
function App() { const [counter, setCounter] = useState(0); const increment = useCallback(() => { setCounter(counter + 1); }, [counter]); const decrement = useCallback(() => { setCounter(counter - 1); }, [counter]); // 疑问代码段开始 const incrementOtherCounter = useCallback(() => { console.log("runner value :", runner()); console.log("this is otherCounter:", otherCounter); setOtherCounter(otherCounter + 1); }, [otherCounter, runner]); const [otherCounter, setOtherCounter] = useState(0); const runner = () => { return "Something ran! :" + counter; }; // 疑问代码段结束 return ( <div className="App"> <button onClick={decrement}>Decrement</button> {` ${counter} `} <button onClick={increment}>Increment</button> <button onClick={incrementOtherCounter}>incrementOtherCounter</button> </div> ); }
调用incrementOtherCounter()时,输出固定为:
runner value :Something ran! :0
this is otherCounter: 0
无论更新counter状态还是重复调用incrementOtherCounter(),counter和otherCounter始终显示为0,不会变化。
场景2
function App() { const [counter, setCounter] = useState(0); const increment = useCallback(() => { setCounter(counter + 1); }, [counter]); const decrement = useCallback(() => { setCounter(counter - 1); }, [counter]); // 疑问代码段开始 const [otherCounter, setOtherCounter] = useState(0); const incrementOtherCounter = useCallback(() => { console.log("runner value :", runner()); console.log("this is otherCounter:", otherCounter); setOtherCounter(otherCounter + 1); }, [otherCounter, runner]); const runner = () => { return "Something ran! :" + counter; }; // 疑问代码段结束 return ( <div className="App"> <button onClick={decrement}>Decrement</button> {` ${counter} `} <button onClick={increment}>Increment</button> <button onClick={incrementOtherCounter}>incrementOtherCounter</button> </div> ); }
调用incrementOtherCounter()能获取到otherCounter的正确值,但runner()返回的counter总是滞后一个更新周期——比如更新counter后,runner()显示的是更新前的值。
场景2运行结果:
场景3
function App() { const [counter, setCounter] = useState(0); const increment = useCallback(() => { setCounter(counter + 1); }, [counter]); const decrement = useCallback(() => { setCounter(counter - 1); }, [counter]); // 疑问代码段开始 const runner = () => { return "Something ran! :" + counter; }; const incrementOtherCounter = useCallback(() => { console.log("runner value :", runner()); console.log("this is otherCounter:", otherCounter); setOtherCounter(otherCounter + 1); }, [otherCounter, runner]); const [otherCounter, setOtherCounter] = useState(0); // 疑问代码段结束 return ( <div className="App"> <button onClick={decrement}>Decrement</button> {` ${counter} `} <button onClick={increment}>Increment</button> <button onClick={incrementOtherCounter}>incrementOtherCounter</button> </div> ); }
此场景中,counter和otherCounter的值都能正确更新,runner()也能实时返回最新的counter值。
场景3运行结果:
核心疑问
我无法理解场景2和场景3的运行逻辑:为什么场景3中incrementOtherCounter()能获取到counter和otherCounter的正确值,而场景2中counter会滞后一个更新周期?
内容的提问来源于stack exchange,提问作者jd singh
相关产品推荐
相关产品推荐

