首页 > 解决方案 > 更新反应js中的对象状态数组

问题描述

我的组件中有以下代码片段,其中我根据状态中的对象生成输入字段。

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

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

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

如何更新此处的值?

主.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)}
    />
  ));

实用程序.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;
}

标签: javascriptreactjs

解决方案


如何更新您的配置文件对象的问题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
        });
    }));
  };

PS你总是可以用简单的方式解决你的问题,比如

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

然而,这不是一个正确的方法,应该避免,因为 React 很大程度上依赖于不变性来进行许多重新渲染和其他优化


推荐阅读