在一个带有使用钩子的React组件的项目中,我试图理解如何正确避免调用绑定到旧状态值的回调。下面的示例说明了该问题(但不是我正在处理的代码)。
import React, { useState, useEffect } from "react"; import ReactDOM from "react-dom"; const Message = () => { const [message, setMessage] = useState(""); function doStuff() { console.log(message); } useEffect(() => { setInterval(doStuff, 1000) }, []); return ( <div> <input type="text" value={message} placeholder="Enter a message" onChange={e => setMessage(e.target.value)} /> <p> <strong>{message}</strong> </p> </div> ); }; const rootElement = document.getElementById("root"); ReactDOM.render(<Message />, rootElement);
这里的问题当然是setInterval将doStuff功能保留为第一次(也是唯一的时间)时的功能。那时message状态为空,因此,间隔函数将每秒输出一个空字符串,而不是实际在文本框中显示的消息。
setInterval
doStuff
message
在我的真实代码中,我遇到了外部事件,这些事件应该触发组件内部的函数调用,并且它们也会遇到相同的问题。
我该怎么办?
您应该useCallback并将其作为对您的影响的依赖项。
useCallback
const doStuff = useCallback(() => { console.log(message); }, [message]); useEffect(() => { const interval = setInterval(doStuff, 1000); return () => clearInterval(interval); // clean up }, [doStuff]);
在这里,当message更新时,它将在doStuff