Javascript 如何使React中的状态不可变

Javascript 如何使React中的状态不可变,javascript,reactjs,react-native,immutability,Javascript,Reactjs,React Native,Immutability,我正在寻找使handleSwitch+setState函数不可变的最佳方法。我目前使用的代码可以工作,但是可变的,我不确定如何使其不可变。我尝试过的所有代码要么不工作,要么给我一个语法错误 这是我的状态被初始化 this.state = { contacts: [], filteredContacts: [], selected: [], contactsSelection: {}, loading: false, }; 我有

我正在寻找使handleSwitch+setState函数不可变的最佳方法。我目前使用的代码可以工作,但是可变的,我不确定如何使其不可变。我尝试过的所有代码要么不工作,要么给我一个语法错误

这是我的状态被初始化

this.state = {
      contacts: [],
      filteredContacts: [],
      selected: [],
      contactsSelection: {},
      loading: false,
    };
我有一个简单的
comp,当用户切换开关时,它会触发下面的命令

handleSwitch = async (contact, added) => {
    if (added) {
      console.log('added', { contact, added });
      return this.setState(prevState => ({
        contactsSelection: {
          ...prevState.contactsSelection,
          [contact.id]: contact,
        },
      }));
    }

    console.log('removed', { contact, added });
    // const { contactsSelection } = this.state;
    return this.setState(prevState => {
      const existingSelection = { ...prevState.contactsSelection };
      delete existingSelection[contact.id]; // <-- make immutable
      return { contactsSelection: existingSelection };
    });
  };
handleSwitch=async(联系人,已添加)=>{
如有(新增){
log('added',{contact,added});
返回此.setState(prevState=>({
联系人选择:{
…prevState.Contacts选择,
[联系人id]:联系人,
},
}));
}
log('removed',{contact,added});
//const{contactsSelection}=this.state;
返回此.setState(prevState=>{
常量existingSelection={…prevState.contactsSelection};

删除现有选择[contact.id];//只是为了澄清:您的代码现在还可以,它不会直接改变状态,而是改变副本

但是,如果你想以不同的方式实现这一点,这里有一个模式:

this.setState(prevState => {
      const { [contact.id]: unusedVariable, ...restContacts } =
          prevState.contactsSelection;
      return { contactsSelection: restContacts };
})
或者使用分解:

this.setState(
  ({ contactsSelection: {[contact.id]: unused, ...filteredContact} })) => 
      ({ contactsSelection: filteredContacts })
);
无论如何,不幸的是,在解构时无法避免引入
unusedVariable
。因此需要您抑制ESLint警告“变量…未使用”


对我来说,你的处理方式更具可读性。

你不是在删除中变异,因为你先创建了一个浅拷贝,然后从该拷贝中删除了密钥。再想一想,它是一个对象,但你没有看到这一点,你的代码已经返回了一个新对象,因此它是不可变的。你的意思是想以更实用的惯用方式执行它吗,这将是一个有点丑陋和效率较低(例如,转换为数组+减少到新对象)啊,感谢这真的很有用,我不知道如何使用rest,{val,…otherVal}