首页 > 解决方案 > 如何更新嵌套在 React 状态中的对象

问题描述

我有一个函数可以更新我的嵌套对象 React 状态,并且我有一个可行的解决方案,但我正在寻找更精致的东西。

所以这是我的状态结构:

state: {
  ...someState,
  object: [
      {
        key1: "1",
        key: "2",
        key3: "3",
        key4: "4"},
      {
        key1: "1",
        key: "2",
        key3: "3",
        key4: "4"}]
    }

目前我正在使用这个函数来更新状态:

handleInputChange = (
    e: ChangeEvent<HTMLInputElement>,
    name: FilterKeys,
    subname?: any,
    index?: number
  ) => {
    e.persist();

      if (subname && index !== undefined) {
        let prop: SomeKeys;
        prop = subname;
        const editedObject = Object.assign({}, this.state.object);
        editedObject[index][prop] = e.target.value;
        const object = Object.keys(editedObject).map((e: any) => {
          return editedObject[e];
        });
        this.setState(
          (prevState: I) => ({
            ...prevState,
            object
          }),
          () => {
            this.someCallback()
          }
        );

    }
  };

我的目标是做这样的事情:

 handleInputChange = (
    e: ChangeEvent<HTMLInputElement>,
    name: FilterKeys,
    subname?: any,
    index?: number
  ) => {
    e.persist();

      if (subname && index !== undefined) {
        let prop: SomeKeys;
        prop = subname;
        this.setState((prevState)=>{
          object: [...prevState.object, prevState.object[index][prop]:3]
})
}

    }
  };

我希望你明白我在说什么。我也知道一个解决方案,我可以为对象分配一些键,所以我可以通过这种方式访问​​它,但我对这样的语法很感兴趣,因为 imo 它看起来更干净

ps 对象数组的长度取决于用户

标签: javascriptarraysreactjstypescript

解决方案


可以使用第三方库吗?我推荐https://lodash.com/docs/4.17.11#set。由于您需要具有不可变状态,您可以使用 lodash/fp ( https://github.com/lodash/lodash/wiki/FP-Guide ):

import set from 'lodash/fp/set'

//...
this.setState(
  currentState => set(['object', index, prop], e.target.value, currentState)
)

set是 lodash.fp 函数。第一个参数是要设置的属性的路径,第二个是新值,第三个是要更新的对象。Lodash/fp 总是创建一个 NEW 对象。

如果您了解函数式编程,curring,则可以将此构造简化为

this.setState(
      set(['object', index, prop], e.target.value)
    )

另一种解决方案

当然,你可以在没有外部库的情况下做到这一点:

this.setState(prevState => ({
    ...prevState,
    object: [
        ...prevState.object.slice(0, index),
        {
            ...prevState.object[index],
            [prop]: e.target.value,
        },
        ...prevState.object.slice(index + 1),
    ],    
}))

推荐阅读