在 useEffect 中反应 setTimeout 和 setState
React setTimeout and setState inside useEffect
我有这段代码,我的问题是为什么在我的回答函数中我得到了 initialState。如何以正确的方式设置状态以在 setTimeout 函数的回调中获得正确的状态?
const App = () => {
const [state, setState] = useState({
name: "",
password: "",
});
useEffect(() => {
setState({ ...state, password: "hello" });
setTimeout(answer, 1000);
}, []);
const answer = () => {
console.log(state);
// we get initial State
};
return <div className="App"></div>;
};
原因是关闭。
answer
函数将始终记录 state
的值,setTimeout()
函数在调用时关闭。
在您的代码中,由于 setTimeout()
函数在 state
包含具有空值的对象时被调用,因此 answer
函数记录该值,而不是记录更新后的值。
要记录最新的状态值,可以使用useRef() hook。此钩子 returns 一个包含名为 current
的 属性 的对象,此 属性 的值是传递给 useRef()
.
的参数
function App() {
const [state, setState] = React.useState({
name: "",
password: "",
});
const stateRef = React.useRef(state);
React.useEffect(() => {
stateRef.current = { ...stateRef.current, password: 'hello'};
setState(stateRef.current);
setTimeout(answer, 1000);
}, []);
const answer = () => {
console.log(stateRef.current);
};
return <div></div>;
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
函数answer
是一个闭包,除了状态的值,它在定义时捕获其作用域内的变量值。当 useEffect 内部的回调被调用时,它得到的 answer 方法会在你的 setState 之前的状态值上关闭。
这就是您要调用的函数 setTimeout
因此即使出现超时,状态的旧值也会延迟。
我有这段代码,我的问题是为什么在我的回答函数中我得到了 initialState。如何以正确的方式设置状态以在 setTimeout 函数的回调中获得正确的状态?
const App = () => {
const [state, setState] = useState({
name: "",
password: "",
});
useEffect(() => {
setState({ ...state, password: "hello" });
setTimeout(answer, 1000);
}, []);
const answer = () => {
console.log(state);
// we get initial State
};
return <div className="App"></div>;
};
原因是关闭。
answer
函数将始终记录 state
的值,setTimeout()
函数在调用时关闭。
在您的代码中,由于 setTimeout()
函数在 state
包含具有空值的对象时被调用,因此 answer
函数记录该值,而不是记录更新后的值。
要记录最新的状态值,可以使用useRef() hook。此钩子 returns 一个包含名为 current
的 属性 的对象,此 属性 的值是传递给 useRef()
.
function App() {
const [state, setState] = React.useState({
name: "",
password: "",
});
const stateRef = React.useRef(state);
React.useEffect(() => {
stateRef.current = { ...stateRef.current, password: 'hello'};
setState(stateRef.current);
setTimeout(answer, 1000);
}, []);
const answer = () => {
console.log(stateRef.current);
};
return <div></div>;
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
函数answer
是一个闭包,除了状态的值,它在定义时捕获其作用域内的变量值。当 useEffect 内部的回调被调用时,它得到的 answer 方法会在你的 setState 之前的状态值上关闭。
这就是您要调用的函数 setTimeout
因此即使出现超时,状态的旧值也会延迟。