使用 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);
【讨论】:
您说“只有一件事,只有一件事,设置新状态并导致重新渲染函数。”那是两件事不是一件事。我有点困惑。 我已经在我的应用中使用当您调用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 后控制台记录状态不返回当前值的主要内容,如果未能解决你的问题,请参考以下文章
useState 在 useEffect 中定义后保持初始状态