有人可以向我解释以下代码段吗?为什么handleClick()无法正常工作(仅设置了newData的数据属性中的1或2)而handleClick2()却正常工作。
我猜测问题是由于循环造成的(因为这是唯一的区别),但是为什么循环会导致这种效果呢?
沙盒链接:https://codesandbox.io/s/restless-surf-u9i5s?file=/src/App.js:0-969
import React, { useState, useEffect } from "react";
import "./styles.css";
const App = () => {
const [newData, setNewData] = useState({
data1: '',
data2: '',
data3: '',
data4: ''
})
const handleClick = () => {
let fields = ['data1', 'data2', 'data3', 'data4']
let field
for (field of fields) {
setNewData(oldState => ({...oldState, [field]: 'test'}))
}
}
const handleClick2 = () => {
setNewData(oldState => ({...oldState, data1: 'test'}))
setNewData(oldState => ({...oldState, data2: 'test'}))
setNewData(oldState => ({...oldState, data3: 'test'}))
setNewData(oldState => ({...oldState, data4: 'test'}))
}
useEffect(() => {
console.log('State: ' + JSON.stringify(newData))
}, [newData])
return (
<div className="App">
<button onClick={handleClick}>Click</button>
<button onClick={handleClick2}>Click2</button>
</div>
);
}
export default App
答案 0 :(得分:1)
原因是:
setNewData
是异步功能。当您以某种方式调用setNewData
时,React将在事件循环中推送其回调函数,然后在主线程为空时在主线程中将其回调。在主setNewData
中调用field
回调函数时,是test4
,因为for (field of fields)
同步函数。 ==>只有setNewData(oldState => ({...oldState, data4: 'test'}))
被呼叫4次。
您可以在field
回调函数中记录setNewData
并查看其值。
for (field of fields) {
console.log(field)
setNewData(oldState => {
console.log(field)
return { ...oldState, [field]: "test" }
})
}