在使用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);
发布于 2019-02-25 22:00:04
默认情况下,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);
发布于 2019-02-25 21:53:17
当您调用setWeather
时,您将触发组件的重现器,它将再次调用此函数。但是,函数中的console.log(weather);
仍然引用useState
返回的第一个值,这是您的原始值。如果你想打印它,你应该这样做:
console.log(e.target.value);
发布于 2020-09-18 08:47:21
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推送到要执行的调用堆栈。
假设您在输入字段中输入"name“。在"nam“之后,状态是"nam",但是当您键入"e”时,这将在webapi中执行,所以当它在web api中时,console.log将记录当前的状态,即“nam”。这就是为什么你总是看到控制台后面一个字符的原因
https://stackoverflow.com/questions/54867616
复制相似问题