React setstate 不将旧状态合并到新状态
React setstate not merging the old state into the new state
根据许多示例,这应该有效:
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]。
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 的依赖项)
这里的问题是closures。
分配给 useEffect
的回调关闭了 _timeseries
在它的词法范围内的初始值,并且它从未更新过。
要修复它,您需要使用 the functional useState
,它在其回调中使用最新状态:
const [_timeseries, $timeseries] = useState({hi:'lol'})
useEffect(() => {
socket.on('plot', e => {
let keyname = Object.keys(e)[0]
$timeseries(timeSeries => {...timeseries, [keyname] : value)})
}
}, [])
根据许多示例,这应该有效:
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]。
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 的依赖项)
这里的问题是closures。
分配给 useEffect
的回调关闭了 _timeseries
在它的词法范围内的初始值,并且它从未更新过。
要修复它,您需要使用 the functional useState
,它在其回调中使用最新状态:
const [_timeseries, $timeseries] = useState({hi:'lol'})
useEffect(() => {
socket.on('plot', e => {
let keyname = Object.keys(e)[0]
$timeseries(timeSeries => {...timeseries, [keyname] : value)})
}
}, [])