Javascript 如何更新父项';每个子挂载上的状态,而不是在所有子挂载后?

Javascript 如何更新父项';每个子挂载上的状态,而不是在所有子挂载后?,javascript,reactjs,Javascript,Reactjs,我试图从子元素中更新父元素的状态 我希望在每个子元素挂载后立即进行更新,因此我使用useffecthook并从那里调用更新函数setData(从父元素传递) 然而,似乎每个随后装入的子元素都忽略了先前装入的子元素对数据所做的更改。也就是说,它在空的数据数组上运行,而对于第二、第三和第四个元素,数组不应再为空 我认为这是因为setData仅在所有元素装载后才计划执行。这是正确的吗?如果是,我该如何解决这个问题 函数父函数(){ const[data,setData]=React.useState

我试图从子元素中更新父元素的状态

我希望在每个子元素挂载后立即进行更新,因此我使用
useffect
hook并从那里调用更新函数
setData
(从父元素传递)

然而,似乎每个随后装入的子元素都忽略了先前装入的子元素对数据所做的更改。也就是说,它在空的
数据
数组上运行,而对于第二、第三和第四个元素,数组不应再为空

我认为这是因为
setData
仅在所有元素装载后才计划执行。这是正确的吗?如果是,我该如何解决这个问题

函数父函数(){
const[data,setData]=React.useState([])
函数更改数据(索引、值){
日志数据()
让new_data=Array.from(数据)
新数据[索引]=值
setData(新数据)
}
函数logData(){
console.log(数据)
}
让子项=数组(4).填充(null).映射((项,索引)=>{
返回
})
返回(
{儿童}
日志数据
)
}
功能儿童(道具){
const ref=React.useRef(null)
React.useffect(()=>{
道具变更数据(ref.current.id,ref.current.id)
}, [])
函数onClickHandler(e){
让元素_id=e.target.id
道具变更数据(元素id,元素id)
}
返回(
小孩
)
}
ReactDOM.render(,document.getElementById('root'))

根据当前状态更新状态时,应始终使用回调版本的
setState
。有关详细信息,请参阅

如果不使用回调版本,则依赖于当前状态的对
setState
的连续调用将相互覆盖,如果react对这些调用进行批处理,则可能会导致不正确的状态

function changeData(index, value) {
    logData()
    setData(current => {
        // current is the current state including all previous calls to setState in this batch
        const new_data = Array.from(current);
        new_data[index] = value;
        return new_data;
    });
}
更新示例:

函数父函数(){
const[data,setData]=React.useState([])
函数更改数据(索引、值){
日志数据()
设置数据(当前=>{
const new_data=Array.from(当前);
新的_数据[索引]=值;
返回新的_数据;
});
}
函数logData(){
console.log(数据)
}
让子项=数组(4).填充(null).映射((项,索引)=>{
返回
})
返回(
{儿童}
日志数据
)
}
功能儿童(道具){
const ref=React.useRef(null)
React.useffect(()=>{
道具变更数据(ref.current.id,ref.current.id)
}, [])
函数onClickHandler(e){
让元素_id=e.target.id
道具变更数据(元素id,元素id)
}
返回(
小孩
)
}
ReactDOM.render(,document.getElementById('root'))


React批处理发生在
useffect
内部的状态更新,当您一次渲染所有子对象时,将立即调用所有效果。您的孩子不需要依赖由兄弟姐妹触发的状态更新。您可以尝试使用forceUpdate()。找到此用于模拟useForceUpdate:。但是,您可以退回到可变数据:
让可变数据=[]
<代码><代码>道具.可变数据[索引]=值;props.changeData(mutableData)另外,您的
changeData
函数不使用当前状态来更新状态。这将导致批量更新相互覆盖。您需要使用回调版本的
setState
。您试图用它解决的原始问题是什么?可能有一种更好的方法,不需要您的孩子知道其他装载兄弟姐妹进行的状态更新。我创建了一个沙盒,其中包含一个可能的解决方案:。这符合你的要求吗?嗯,我想它不起作用。请运行代码段并查看,并在每个子装载上调用
logData()
的输出-它仍然都是空数组,不是先前子装载调整的数据。@barciewicz在子装载的渲染之间不能调用任何东西。react中的呈现是一个单独的过程,在这两个过程之间执行的不是代码的任何部分。首先,它将渲染已更新的每个组件,并且仅在更新之后才会调用任何
useffect
。没有“每个子支架之间”。它们同时挂载,然后调用所有效果。这就是为什么在第一次装载时,它们都会看到一个空状态。我还为答案添加了可能的解决方案。如果它解决了你的问题,请随意接受它。