You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何管理对象数组状态,实现表单属性更新与数组元素递增

解决方案

实现逻辑

  • 给通用表单配置项添加field字段,关联stocks对象对应的属性名
  • 父组件封装状态更新函数,通过「表单下标+字段名」精准定位到需要修改的属性,更新stocks数组
  • 遍历生成每个表单时,动态为表单元素绑定对应的值和更新回调
  • 新增表单功能直接修改stocks数组即可自动渲染空白表单

修改后代码

父组件 AddStocksSection

import { useState } from "react";
import SectiontWrapper from "../../primitives/section-wrapper";
import SectionHeader from "../../primitives/section-header";
import ExpandableForm from "../../constructs/expandable-form";

const AddStocksSection = () => {
  const [stocks, setStocks] = useState([
    {
      market: "",
      stock: "",
      amount: "",
    },
  ]);

  // 表单配置新增field字段关联对应属性
  const formElements = [
    {
      label: "Select a market",
      placeholder: "Select",
      required: true,
      disabled: "",
      type: "select",
      field: "market",
      options: [
        {
          name: "Select",
          value: "select",
        },
        {
          name: "AEX",
          value: "aex",
        },
      ],
    },
    {
      label: "Select a stock",
      placeholder: "Select",
      required: true,
      disabled: "",
      type: "select",
      field: "stock",
      options: [
        {
          name: "Select",
          value: "select",
        },
        {
          name: "Googl",
          value: "googl",
        },
      ],
    },
    {
      label: "How many do you have",
      placeholder: "100",
      required: true,
      disabled: "",
      type: "number",
      field: "amount",
    },
  ];

  // 表单值更新处理函数
  const handleStockChange = (formIndex, field, value) => {
    setStocks(prevStocks => {
      const updatedStocks = [...prevStocks];
      updatedStocks[formIndex][field] = value;
      return updatedStocks;
    });
  };

  // 新增空白表单
  const addNewStockForm = () => {
    setStocks(prev => [...prev, { market: "", stock: "", amount: "" }]);
  };

  return (
    <SectiontWrapper>
      <SectionHeader>Add some stocks</SectionHeader>
      {stocks.map((stock, i) => (
        <ExpandableForm
          key={i}
          expanded={false}
          // 动态生成当前表单专属的配置项,绑定对应值和回调
          formElements={formElements.map(el => ({
            ...el,
            value: stock[el.field],
            onChange: (e) => handleStockChange(i, el.field, e.target.value)
          }))}
          addStock={addNewStockForm}
        />
      ))}
    </SectiontWrapper>
  );
};

export default AddStocksSection;

子组件 ExpandableForm

import {
  FormWrapper,
  ButtonGroup,
  FormContainer,
} from "./expandable-form-style";
import ButtonOutlined from "../../primitives/button-outlined";
import ButtonSolid from "../../primitives/button-solid";
import Loader from "../loader";
import getFormElement from "../../../tools/getFormElement";

const ExpandableForm = ({
  submitForm,
  isDisabled,
  formElements,
  isLoading,
  expanded,
  addStock // 接收父组件传的新增表单方法
}) => {
  return (
    <FormWrapper expanded={expanded}>
      <FormContainer>
        {formElements.map((formElement, i) => {
          const FormElement = getFormElement(formElement.type);
          return (
            <FormElement
              key={i}
              label={formElement.label}
              placeholder={formElement.placeholder}
              value={formElement.value}
              onChange={formElement.onChange}
              disabled={formElement.disabled}
              type={formElement.type}
              options={formElement.options}
            />
          );
        })}
        <ButtonGroup>
          <ButtonOutlined disabled={isLoading} color="venetianRed">
            Skip
          </ButtonOutlined>
          <ButtonSolid
            onClick={addStock} // 绑定新增表单回调
            disabled={isLoading || isDisabled}
            color="yellowGreen"
          >
            Add
          </ButtonSolid>
          <ButtonSolid
            onClick={() => submitForm()}
            disabled={isLoading || isDisabled}
            color="royalVessel"
          >
            {isLoading ? <Loader /> : "Next"}
          </ButtonSolid>
        </ButtonGroup>
      </FormContainer>
    </FormWrapper>
  );
};

export default ExpandableForm;

内容的提问来源于stack exchange,提问作者Ricardo de Vries

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 21:15:06