我有一个问题,我不明白为什么钩子返回undefined:
import React, { useEffect, useState } from 'react';
function App(){
const [globalVariable, setGlobalVariable] = useState();
useEffect(()=>{
const test = 5
console.log(test) // return 5
setGlobalVariable(test)
console.log(globalVariable) // return undefined
},[]);
return (
<div>
</div>
);
}
export default App;
我该怎么做才能直接为globalVariable设置一个新值?
8条答案
按热度按时间tnkciper1#
正如其他成员所提到的,setState在基于队列的系统中异步运行。这意味着如果你想执行状态更新,这个更新将堆积在队列上。但是,它不会返回Promise,所以你不能使用
.then
或wait
。正因为如此,我们需要意识到在React中操作状态时可能出现的问题。假设我们有:
由于setCount是异步的,
console.log
将返回更新之前的值(这里是0)。在您的情况下,它将返回undefined
,因为您没有在useState钩子中传递任何初始状态。您所做的另一件不同的事情是从useEffect
钩子内部触发状态更改,但这对眼前的问题来说并不重要要解决这个问题,一个好的做法是将新状态存储在另一个变量中,如下所示:
这基本上回答了你的问题。
但是,还有其他情况下,状态更新可能不会像预期的那样。重要的是要注意这些情况,以避免可能的错误。例如,让我们假设我们连续多次更新给定的状态,如:
这里,
console.log
仍然返回0,原因与问题1中描述的相同。但是,如果您在应用中的某个位置使用count
状态,您将看到onClick
事件后的最终值为1,而不是3。以下是如何解决此问题:
通过向setState传递一个函数,使用队列上的前一个值而不是初始值来计算新状态。
作为最后一个例子,假设我们在尝试改变状态之后调用了一个函数,但是这个函数依赖于状态值。由于操作是异步的,所以这个函数将使用“旧”的状态值,就像问题#1一样:
注意在这个问题中,我们有一个依赖于外部变量的函数
onCountChange
(count
)。所谓外部,我的意思是这个变量没有在onCountChange
的作用域内声明。它们实际上是兄弟。(两者都位于Button
范围内)。现在,如果你熟悉“纯函数”、“幂等”和“副作用”的概念,您将意识到,我们在这里遇到的是一个副作用问题--我们希望在状态更改之后发生一些事情。粗略地说,每当你需要在React中处理一些副作用时,这都是通过useEffect钩子来完成的。所以,要解决我们的第三个问题,我们可以简单地这样做:
在上面的解决方案中,我们将
onCountChange
的内容移动到useEffect,并添加count
作为依赖项,因此每当它发生变化时,效果就会被触发。r7knjye22#
两件事:
useState
有一个初始值,默认为undefined。setGlobalVariable
不是同步操作。更改它不会立即改变globalVariable
。作用域中的值将保持不变,直到下一个渲染阶段。6ju8rftf3#
因为state只有在组件重新渲染时才有新的值。所以只需要像这样将
console.log(globalVariable)
放在useEffect之外:xam8gpfp4#
这是因为组件没有重新渲染。你需要在渲染之间保持值,为此你需要使用useState将变量更改为状态。为了更好地理解,请查看下面的代码:
6ie5vjzr5#
1.这是因为React状态更新是基于队列的系统。它不会立即更新。但是如果你渲染一个全局变量值,你会得到所需的值。
1.如果你在基于类的组件中也有同样的需求,那么你需要将回调函数传递给setState。它会在状态更新时立即执行。
this.setState(stateupdate,callback)
一旦状态被更新,回调函数将以最新的状态执行。
}
yxyvkwin6#
这在官方文档§caveats中有很好的解释:
set
函数只更新 next render的状态变量。如果在调用set
函数后读取状态变量,则仍将获得调用前屏幕上的旧值。特别是§故障排除:我已更新状态,但日志记录为我提供了旧值
piah890a7#
出现错误的原因是,最初状态变量userData未定义。您试图在JSX代码中访问userData的name属性,但它尚未定义。因此,您需要添加一个条件,以在渲染JSX代码之前检查userData是否存在。您可以使用&&运算符来实现此目的。
您可以使用“{userData &&
{userData.name}
}”in your JSX in react
7gyucuyw8#
setGlobalVariable(test);需要一些时间,并且你试图在useEffect中执行它,它只运行一次,你应该使用setTimeOut函数花一些时间来显示状态,尝试这个并让我知道它是否工作。