在React JS中更新对象状态数组

时间:2020-06-25 08:32:46

标签: javascript reactjs

我从组件中获得以下代码段,其中根据状态下的对象生成Input字段。

我可以成功生成输入字段,但是收到错误消息:

TypeError:无法读取未定义的属性“ map”

每当我在输入字段中键入时,都指向 Utils.js 中的方法arrayObjToArrary

如何更新here的值?

Main.js

import Input from "../UI/Input";
import {arrayObjToArrary} from "../../utility/Utils.js";

const [profiles, setProfiles] = useState({
    controls: [
      {
        network: {
          elementType: "input",
          elementConfig: {
            type: "text",
            label: "Network",
          },
          value: "Twitter",
        },
      },
      {
        username: {
          elementType: "input",
          elementConfig: {
            type: "text",
            label: "Username",
          },
          value: "@john",
        },
      },
      {
        url: {
          elementType: "input",
          elementConfig: {
            type: "url",
            label: "URL",
          },
          value: "https://example.xyz",
        },
      },
    ],
  });
  
  const profilesControls = arrayObjToArrary(profiles.controls);
  const arrayInputHandler = (event, index, identifier) => {
    const list = [...profiles.controls];
    list[index][identifier] = event.target.value;
    setProfiles(list);
  };
  
  let profileField = profilesControls.map((formElement) => (
    <Input
      label={formElement.config.elementConfig.label}
      key={formElement.index}
      type={formElement.config.elementType}
      elementConfig={formElement.config.elementConfig}
      value={formElement.config.value}
      changed={(event) => arrayInputHandler(event, formElement.index, formElement.id)}
    />
  ));

Utils.js

export const arrayObjToArrary = (controls) => {
  const formElementsArray = controls.map((item,index) =>({
    id: Object.keys(item)[0],
    index:index,
    config: item[Object.keys(item)[0]],
  }))
  return formElementsArray;
}

2 个答案:

答案 0 :(得分:1)

如何更新arrayInputHandler中的配置文件对象。当您将列表传递给setProfiles时,它将其结构从对象更改为数组。

此外,您也不能更改原始状态值。正确的更新方式如下

const arrayInputHandler = (event, index, identifier) => {
    const value = event.target.value;
    setProfiles(prev => ({
        ...prev,
        controls: profiles.controls.map((controls, i) => {
           if(i === index) {
              return {
                ...controls, [identifier]: {
                  ...controls[identifier],
                  value
               }
              }
           }
           return controls
        });
    }));
  };

P.S。您总是可以以简单的方式解决问题,例如

const arrayInputHandler = (event, index, identifier) => {
    const list = [...profiles.controls];
    list[index][identifier] = event.target.value;
    setProfiles({profile:list});
  };

但是它不是正确的方法,应避免使用它,因为react在很多情况下都依赖于不变性,因此需要重新渲染和进行其他优化

答案 1 :(得分:1)

您可以尝试

const arrayInputHandler = (event, index, identifier) => {
    const list = [...profiles.controls];
    list[index][identifier].value = event.target.value;
    setProfiles({ controls: list });
};

在此处codesandbox