React setstate不将旧状态合并到新状态



根据许多例子,这应该有效:

const [_timeseries, $timeseries] = useState({hi:'lol'})
useEffect(() => {
socket.on('plot', e => {
let keyname = Object.keys(e)[0]
$timeseries({..._timeseries, [keyname] : value)})
}
}, [])
console.log(_timeseries) // here results in the initial state, not the set state

第一次合并时,它就工作了。但一旦一个带有另一个主题的新事件进入,它就会再次取代整个事件。不是用[keyname]添加新密钥,而是替换旧的[keyname]。

这里的问题是闭包。

分配给useEffect的回调关闭了其词法范围中_timeseries的初始值,并且它从未更新。

要修复它,您需要使用函数useState,它在回调中使用最新的状态:

const [_timeseries, $timeseries] = useState({hi:'lol'})
useEffect(() => {
socket.on('plot', e => {
let keyname = Object.keys(e)[0]
$timeseries(timeSeries => {...timeseries, [keyname] : value)})
}
}, [])

useState钩子为您提供了一个函数,该函数将状态完全替换为新值(不合并(:https://reactjs.org/docs/hooks-state.html

However, unlike this.setState in a class, updating a state variable always replaces it instead of merging it.

您可以将setState与一个函数一起使用,并自行合并:

$timeseries((old) => ({...old, [keyname] : value)}))

如果你在没有函数的情况下使用它,它可能会有旧的值(因为你没有将其指定为useEffect的依赖项(

最新更新