使用 useState 后控制台记录状态不返回当前值

Posted

技术标签:

【中文标题】使用 useState 后控制台记录状态不返回当前值【英文标题】:console log the state after using useState doesn't return the current value 【发布时间】:2019-07-18 22:34:09 【问题描述】:

在使用reactjs useState()钩子后使用console.log(),不返回该状态的当前值,我该如何处理?

这是案例的代码,试着弄清楚控制台日志显示的是什么。

import React,  useState  from "react";
import ReactDOM from "react-dom";

function Weather() 
  const [weather, setWeather] = useState();

  return (
    <input
      value=weather
      onChange=(e) => 
        setWeather(e.target.value);
        console.log(weather);
      
    />
  );


const rootElement = document.getElementById("root");
ReactDOM.render(<Weather />, rootElement);

【问题讨论】:

是的,因为组件还没有更新。你应该使用登录useEffect 【参考方案1】:

useState 默认情况下只做一件事,只做一件事,设置新状态并重新渲染函数。它本质上是异步的,因此默认情况下,通常在它运行之后运行的方法。

在您的示例中,在新加载页面时,键入“s”会导致 useState 更改状态,但由于它是异步的,console.log 将使用旧状态值调用,即undefined(因为你没有设置值。如果你愿意,你应该考虑设置一个初始状态)

const [weather, setWeather] = useState('');    // Set the intial state

真正读取状态值的唯一方法是使用useEffect,它在组件重新渲染时调用。你的方法就变成了:

import React,  useEffect, useState  from 'react';
import ReactDOM from 'react-dom';

function Weather() 
    const [weather, setWeather] = useState('');

    useEffect(() => console.log(weather), [weather]);

    const changeValue = event => setWeather(event.target.value);

    return <input value=weather onChange=changeValue />;


const rootElement = document.getElementById('root');
ReactDOM.render(<Weather />, rootElement);

【讨论】:

您说“只有一件事,只有一件事,设置新状态并导致重新渲染函数。”那是两件事不是一件事。我有点困惑。 我已经在我的应用中使用 尝试过这个确切的事情,它是否有理由返回未定义?【参考方案2】:

当您调用setWeather 时,您会触发组件的重新渲染,该组件将再次调用此函数。但是,函数内部的console.log(weather); 仍然引用useState 返回的第一个值,这是您的原始值。如果你想打印它,你应该这样做:

console.log(e.target.value);

【讨论】:

【参考方案3】:
onChange=(e) => 
    setWeather(e.target.value);
    console.log(weather);
  

当这个函数被触发时,由于setWeather是异步的,它会被传递给web api。 javascript 引擎不处理此功能。 wep api 处理这个,当它完成时,作为 web api 一部分的事件循环将它传递给调用堆栈。

调用栈是函数被执行的地方。一旦异步函数被传递给 web api,无论它的执行时间如何(即使它有 0 秒超时),它们都不会移动到调用堆栈,除非 javascript 引擎完成同步代码的执行。一旦调用堆栈空闲,事件循环将把函数传递给调用堆栈执行。

所以在您的代码中,onChange() 被传递给调用堆栈。在这个函数内部,必须执行 2 个函数。因为setWeather 是异步的,所以它进入web api,获取e.target.value,同时执行console.log。当调用栈中没有同步代码时,事件循环将setWeather推送到调用栈中执行。

假设您在输入字段中输入“名称”。在“nam”之后,状态是“nam”,但是当你键入“e”时,这将在 webapi 中执行,所以当它在 web api 中时,console.log 将记录当前状态为“nam”。这就是为什么你总是会在控制台后面看到一个字符

【讨论】:

以上是关于使用 useState 后控制台记录状态不返回当前值的主要内容,如果未能解决你的问题,请参考以下文章

setstate 回调后 useState 不改变?

useState 在 useEffect 中定义后保持初始状态

无法在异步方法中设置 useState 变量并控制台记录它

无法获取更新后的状态值 useState 和 UseEffect

HOOK—useState、useEffect的使用

如何立即更新 react useState?