我有一个动态的对象列表,需要为它们生成开关组件。
var dynamicObject = [{ name: 'first item', value: false }, { name: 'second item', value: true}, ..];
this.setState({ dynamicObject });
要更新
onSwitchChange = (name, newValue) => {
var obj = {...this.state.dynamicObject};
obj.find(x => x.name === name).value = newValue;
this.setState({ dynamicObject: obj });
}
但是,如果我在多个开关上单击得足够快,第一个开关将发生变化,而其他开关将恢复为旧状态。这是由于setState
的异步性质。我该如何解决这个问题?
EDIT1
我也尝试过这个。仍然无法正常工作
this.setState(currentState => {
var obj = currentState.dynamicObject;
obj.find(x => x.name === name).value = newValue;
return { dynamicObject: obj };
});
EDIT2
我正在使用render()
中的函数创建元素,
const SwitchItem = ({ label, value, onSwitchChange }) => {
return (
<View style={styles.wrapper}>
<View>
<Text>{label}</Text>
</View>
<View>
<Switch value={value} onValueChange={onSwitchChange} />
</View>
</View>
);
}
如果我将其用作循环中的组件
<SwitchItem key={i} label={item.name} value={item.value} onSwitchChange={val => onSwitchChange(item.name, val) } />
失败。
但是,如果执行此操作,则EDIT1中的方法有效
{SwitchItem({label: item.name, value: item.value, onSwitchChange: val => onSwitchChange(item.name, val) })}
两种方法有什么区别?
现在,如果我快速单击多个开关,它们会发生变化,但是如果我双击一个关闭的开关,它将只保持在“开”位置,而忽略了连续的单击一段时间?。
答案 0 :(得分:0)
this.setState
不会立即更新状态。而是将更改和更新状态分批排队。当您快速调用onSwitchChange
时,如果尚未处理该批处理,则var obj = {...this.state.dynamicObject}
行可能正在使用旧数据。
解决方法是将this.setState
与函数参数而不是对象一起使用。当React处理批处理时,它将使用最新状态对象调用该函数。
onSwitchChange = (name, newValue) => {
this.setState(({ dynamicObject }) => {
var obj = {...this.state.dynamicObject};
obj.find(x => x.name === name).value = newValue;
return { dynamicObject: obj }
});
}
有关更多信息,请查看React.setState