在 useEffect 内反应 setTimeout 和 setState [英] React setTimeout and setState inside useEffect

查看:61
本文介绍了在 useEffect 内反应 setTimeout 和 setState的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个代码,我的问题是为什么在我的答案函数中我得到了初始状态.如何以正确的方式设置状态以在 setTimeout 函数的回调中获得正确的状态?

const App = () =>{const [状态,设置状态] = useState({名称:",密码:",});useEffect(() => {setState({ ...state, 密码: 你好"});设置超时(答案,1000);}, []);const 答案 = () =>{控制台日志(状态);//我们得到初始状态};return 

;};

解决方案

原因是闭包.

answer 函数将始终记录 setTimeout() 函数在调用时关闭的 state 的值.

在您的代码中,由于 setTimeout() 函数在 state 包含具有空值的对象时被调用,answer 函数会记录该值,而不是记录更新的值.

要记录 state 的最新值,您可以使用 useRef() 钩.这个钩子返回一个对象,它包含一个名为 current 的属性,这个属性的值是传递给 useRef() 的参数.

function App() {const [state, setState] = React.useState({名称: "",密码: "",});const stateRef = React.useRef(state);React.useEffect(() => {stateRef.current = { ...stateRef.current,密码:'你好'};setState(stateRef.current);设置超时(答案,1000);}, []);const 答案 = () =>{控制台日志(stateRef.current);};返回<div></div>;}ReactDOM.render(, 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>

I have this code and my question is why inside my answer function I get the initialState. How to set the state in a proper way to get the right one inside a callback of setTimeout function?

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>;
};

解决方案

The reason is closure.

answer function will always log that value of state which setTimeout() function closed over when it was called.

In your code, since setTimeout() function is called when state contains an object with empty values, answer function logs that value, instead of logging the updated value.

To log the latest value of state, you can use useRef() hook. This hook returns an object which contains a property named current and the value of this property is the argument passed to 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>

这篇关于在 useEffect 内反应 setTimeout 和 setState的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆