React中 setStatez中数组和对象的修改方式?

一、为什么React中修改数组时不能使用数组的可变方法。


在React中使用setState修改数组的值时,不推荐使用数组的可变方法(如push、unshift等)。这是因为React会对比新旧状态,在发现状态变化后,更新组件的渲染。但当你调用可变方法修改数组时,虽然数组已经被改变,但数组的地址并没有发生变化,React并不会察觉到这个变化,也就不会更新组件。


二、我们可以使用以下几种方法。

(1)对数组进行修改

 // 1、修改object中某项
 
this.setState({
  object: {...object, key: value}
});
  // 2、删除数组首位
 
array.splice(0, 1);
this.setState({
  array
});
  // 3、删除数组尾部
 
array.splice(array.length - 1);
this.setState({
  array
});
  // 4、删除数组任意一项
 
array.splice(index, 1);
this.setState({
  array
});
  // 5、数组尾部添加一项
 
this.setState({
  array: [...array, item]
});
 //  6、数组头部添加一项
 
this.setState({
  array: [item, ...array]
});
  7、数组任意位置添加一项
 
array.splice(index, 0, item);
this.setState({
  array
});
 // 8、修改数组中任意一项中值
 
function updateArrayItem(index, key, value) {
  this.setState({
    array: array.map((item, _index) => _index == index ? {...item, [key]: value} : item)
  });
}

(2)复杂数据类型进行修改

  • 复杂类型修改
this.setState(prevState => return newState);

返回一个新的state对象,可以修改最复杂的state,一般不建议使用。

(3)对象类型进行修改
state = {
     list: {
        objA: {
          name: 'A',
          age: 20
        },
        objB: {
          name: 'B',
          age: 25
        },
        objC: {
          show: false
        },
        objD: 'D'
      }
}

方案一(作用于对象中的深层级和第一层级):

  this.setState({
     list: {
         ...this.state.list,
          objA: {
             ...this.state.list.objA,
                  name: 'A1'
                }
              }
            })

方案二(作用对象中的第一层级):

  let data = Object.assign({}, this.state.list, {objD: 'D1'})
    this.setState({
              list: data
            })

方案三(作用于对象中的深层级和第一层级):

  let data = this.state.list;
      data.objA.name = 'A1';
      data.objD = 'D1';
      this.setState({
              list: data
            })

总结:

方案一 |

                使用场景 ;多层级和单一层级都存在。

                缺点:|写法麻烦,单次对象赋值,对象层级多的时候,容易遗漏
方案二 |        

               使用场景:只适用与第一层级 

                     缺点:只适用第一层级
方案三 |

               使用场景:多层级和单一层级都存在

                      缺点:若存在深层及和单一层级的,需要多次赋值