更新状态后在功能中记录状态,仍会输出初始状态

时间:2020-03-08 09:56:58

标签: javascript reactjs react-hooks

在尝试从React中的功能调整状态时遇到了不寻常的事情。

一个简单的示例包括尝试更改保存字符串的状态testState。我认为我可以在函数中使用setTestState()来更改字符串并查看其更改后的值。但是,我注意到console.log(testState)输出相同的状态,因此看来setTestState(...)没有做任何事情。但是,呈现状态使用更新后的字符串。

那么console.log(tempState)为什么显示原始状态而不显示新状态?我一直找不到答案。我使用的代码如下。任何建议都会很棒。

import React, { useState, useEffect } from "react";
import "./App.css";

function App() {  
  const [testState, setTestState] = useState("previous state");

  useEffect(() => {
    setGrid();
  }, []);

  const setGrid = () => {
    console.log(testState);         // output: "previous state"
    setTestState("changed state");
    console.log(testState);         // output: "previous state", expected "changed state"
  }

  return (
    <div>      
      {testState}
    </div>
  );
}

export default App;

2 个答案:

答案 0 :(得分:1)

主要问题是setTestState()异步处理更改。这就是为什么第二个console.log()中也有旧状态的原因,因为它是同步运行的。

要捕获状态更改,可以使用useEffect()钩子。

我建议使用以下内容:

const [testState, setTestState] = useState('previous state');

useEffect(() => {
   setGrid();
}, []);

const setGrid = () => {
   console.log('oldState', testState);

   setTestState('changed state');
};

useEffect(() => {
   console.log('newState', testState);

   // ... actions after state change
}, [testState]);

建议阅读:Using the Effect Hook

我希望这会有所帮助!

答案 1 :(得分:1)

setTestState()是一个异步方法。与setState()方法类似。因此,您的第二个console.log(testState)在完全执行setTestState()之前运行,因此,您的console.log(testState)打印旧状态。

如果要确保setTestState()方法是否正常工作,可以对其使用 useEffect(),该方法的工作原理类似于componentDidUpdate。

useEffect( () => {
    console.log("updated state", testState)
}, [ 'testState' ]);