Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React setstate不将旧状态合并到新状态_Javascript_Reactjs_Closures_React Hooks_Lexical Closures - Fatal编程技术网

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

Javascript React setstate不将旧状态合并到新状态,javascript,reactjs,closures,react-hooks,lexical-closures,Javascript,Reactjs,Closures,React Hooks,Lexical Closures,根据许多例子,这应该是可行的: 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

根据许多例子,这应该是可行的:

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钩子为您提供了一个函数,该函数用一个新值完全替换状态(不合并):

您可以将setState与函数一起使用,然后自己将其合并:

$timeseries((old) => ({...old, [keyname] : value)}))
如果您在没有函数的情况下使用它,它可能具有旧值(因为您没有将其指定为useEffect的依赖项)

这里的问题是

分配给
useffect
的回调将关闭
\u timeseries
在其词法范围内的初始值,并且从未更新

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

const [_timeseries, $timeseries] = useState({hi:'lol'})

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

}, [])

是的,我就是这么做的。合并有效,只是在第二次停止工作后。@BTj84VvNNL2gh9GC如果您没有在$timeseries中使用函数,那么您使用的是变量_timeseries您应该使用函数,否则您可能会得到错误的值如果不缺少useEffect依赖项,那么没有函数也可以工作?是,但在你的情况下,我会使用一个函数,否则你将不得不取消订阅并重新订阅套接字。
const [_timeseries, $timeseries] = useState({hi:'lol'})

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

}, [])