【发布时间】:2020-01-10 20:12:17
【问题描述】:
编辑(2020 年 6 月 22 日):由于这个问题有一些新的兴趣,我意识到可能存在一些混淆点。所以我想强调一下:问题中的示例旨在作为玩具示例。它不能反映问题。引发这个问题的问题是使用第三方库(对其控制有限),该库将回调作为函数的参数。为该回调提供最新状态的正确方法是什么。在反应类中,这将通过使用this 来完成。在 React Hooks 中,由于 state 被封装在 React.useState() 的函数中的方式,如果一个回调 get 通过React.useState() 获得状态,它将是陈旧的(设置回调时的值) .但是如果它设置状态,它将可以通过传递的参数访问最新状态。这意味着我们可以通过将状态设置使其与原来的状态相同,从而在使用 React 钩子的回调中获得最新状态。这可行,但违反直觉。
-- 下面继续原始问题--
我正在使用 React 钩子并尝试从回调中读取状态。每次回调访问它时,它都会返回其默认值。
使用以下代码。无论我点击多少次,控制台都会继续打印Count is: 0。
function Card(title) {
const [count, setCount] = React.useState(0)
const [callbackSetup, setCallbackSetup] = React.useState(false)
function setupConsoleCallback(callback) {
console.log("Setting up callback")
setInterval(callback, 3000)
}
function clickHandler() {
setCount(count+1);
if (!callbackSetup) {
setupConsoleCallback(() => {console.log(`Count is: ${count}`)})
setCallbackSetup(true)
}
}
return (<div>
Active count {count} <br/>
<button onClick={clickHandler}>Increment</button>
</div>);
}
const el = document.querySelector("#root");
ReactDOM.render(<Card title='Example Component' />, el);
你可以找到这个代码here
我在回调中设置状态没有问题,只是在访问最新状态时。
如果我猜测一下,我认为任何状态变化都会创建 Card 函数的新实例。并且回调指的是旧的。根据https://reactjs.org/docs/hooks-reference.html#functional-updates 的文档,我想到了在回调中调用 setState 并将函数传递给 setState 的方法,以查看是否可以从 setState 中访问当前状态。更换
setupConsoleCallback(() => {console.log(`Count is: ${count}`)})
与
setupConsoleCallback(() => {setCount(prevCount => {console.log(`Count is: ${prevCount}`); return prevCount})})
你可以找到这个代码here
这种方法也没有奏效。 编辑:实际上第二种方法确实有效。我只是在我的回调中有一个错字。这是正确的做法。我需要调用 setState 来访问之前的状态。即使我无意设置状态。
我觉得我对 React 类采取了类似的方法,但是。为了代码的一致性,我需要坚持使用 React Effects。
如何从回调中访问最新的状态信息?
【问题讨论】:
-
我不相信它是上述的副本。因为它不是关于设置状态是异步的事实。但是关于状态 forever 在回调中是陈旧的。现在我找到了答案,但它可能与stackoverflow.com/questions/56782079/react-hooks-stale-state 重复。然而,我认为这指向了一个有趣的结果,即反应钩子如何管理状态。即您需要调用设置状态的函数,以便在回调中访问正确的状态。即使您不打算更改状态,这仍然是正确的。
-
是的,你是对的,它是关于函数闭包的工作原理。这是stackoverflow.com/questions/57471987/… 的主题之一
-
也许 Dan Abramov 的这篇博客会有所帮助:overreacted.io/making-setinterval-declarative-with-react-hooks,它解释了为什么混合使用 hooks 和 setInterval 确实令人困惑,而且一开始似乎不起作用。 TL:DR 基本上是因为关闭,您需要用下一个状态值“重新封装”回调。
-
是的,我认为它是这样的,因为如果我使用类,我会将
this绑定到回调,但看不到如何使用效果。我尝试了一些方法,例如将状态变量的 getter 作为回调的参数。但没有任何效果。无论如何,在查看了每个人共享的所有链接之后,我仍然不清楚。除了调用它的状态设置函数(特别是当我不想想改变它的状态时),有没有办法从另一个上下文中读取组件的状态?
标签: javascript reactjs react-hooks