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

IT技术 javascript reactjs
2021-01-20 17:55:37

通过console.log()使用reactjs后useState()挂机,不返回此状态下的电流值,我该如何处理呢?

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

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);
3个回答

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);
你说“一件事只有一件事,设置新状态并重新渲染函数。” 那是两件事而不是一件事。我有点困惑。
2021-03-19 17:55:37
我已经使用 <InputText> 在我的应用程序中尝试过这个确切的事情,它是否有返回未定义的原因?
2021-03-24 17:55:37

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

console.log(e.target.value);
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”。这就是为什么你总是会看到控制台后面一个字符