根据许多例子,这应该有效:
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的依赖项(