setState是否与useState挂钩异步?

时间:2020-07-13 17:49:30

标签: javascript reactjs react-hooks use-state

function App() {
  const [name, setName] = useState('');
  
  // *****************
  const onNameChange = (e) => {
    setName(e.target.value)
    console.log(name)   
    
  }

  const onSubmit = (e) => {
    e.preventDefault();
    setName('')
  }

  return (
    <div className="App">

      <form onSubmit={onSubmit}>
        <input type="text" value={name} onChange={onNameChange} />
        <button>submit</button>
      </form>

    </div>
  )
}
export default App;

为什么我无法在控制台中记录全名? 例如: 如果我在表格中填写“授予”,则日志将如下所示:

  1. 当键入“ a”控制台为空白时
  2. 当键入“ am”控制台为“ a”时
  3. 当键入“ ami”控制台为“ am”时
  4. 当键入“ amit”控制台为“ ami”时

为什么输出少一个字符? setName是异步的吗?如果是,那么为什么异步/等待对此没有任何影响?

注意:类组件中的相同逻辑工作正常。

2 个答案:

答案 0 :(得分:1)

您正在控制台记录旧值;添加useEffect来控制台记录新值:

  useEffect(()=> {
    console.log(name)   
  }, [name])

在类组件中,相同的逻辑不能正常工作(请参见代码段)。如果从处理程序中调用,控制台日志仍会以旧状态进行响应;您将必须在componentDidUpdate中控制台日志以获取新结果。

class App extends React.Component {
  state = { name: "" };
  // *****************
  onNameChange = e => {
    this.setState({ name: e.target.value });
    console.log("onNameChange:", this.state.name);
  };

  componentDidUpdate() {
    console.log("componentDidUpdate:", this.state.name);
  }

  onSubmit = e => {
    e.preventDefault();
  };

  render() {
    return (
      <div className="App">
        <form onSubmit={this.onSubmit}>
          <input
            type="text"
            value={this.state.name}
            onChange={this.onNameChange}
          />
          <button>submit</button>
        </form>
      </div>
    );
  }
}

ReactDOM.render(<App/>, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

答案 1 :(得分:0)

就像通过扩展React.Component创建的Class组件中的setState一样,使用useState钩子在函数中提供的更新程序进行的状态更新也是异步的,不会立即反映出来。您不能使用netstandard2.1,因为它假定在1个渲染期间不变。 Read more

您可以通过读取render函数中的值(而不是嵌套函数中的值)来解决此问题,或者执行以下操作:

await useState()