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

如何基于键数组访问和修改嵌套对象?(React+MUI场景)

解决方案

1. 实现嵌套值的访问与更新工具函数

核心是通过两个工具函数,处理路径数组访问嵌套值和不可变更新嵌套值的逻辑:

访问嵌套值

// 根据keyList安全获取嵌套对象的值,路径不存在时返回undefined
const getNestedValue = (obj, keyList) => {
  return keyList.reduce((current, key) => {
    return current?.[key] ?? undefined;
  }, obj);
};

不可变更新嵌套值

// 根据keyList不可变更新嵌套对象的值,自动创建不存在的中间层级
const setNestedValue = (obj, keyList, newValue) => {
  const newObj = {...obj};
  let currentLayer = newObj;

  // 遍历到倒数第二个键,每一层都浅拷贝保证不可变性
  for (let i = 0; i < keyList.length - 1; i++) {
    const key = keyList[i];
    // 若当前层级无此键或不是对象,创建空对象
    currentLayer[key] = {...(currentLayer[key] ?? {})};
    currentLayer = currentLayer[key];
  }

  // 设置最后一个键的新值
  const lastKey = keyList[keyList.length - 1];
  currentLayer[lastKey] = newValue;

  return newObj;
};

2. 递归表单组件实现

结合MUI的TextField,封装递归表单字段组件,传入路径数组、表单状态和更新函数即可:

import { TextField } from '@mui/material';

const RecursiveFormField = ({ form, setForm, keyList, label }) => {
  const currentValue = getNestedValue(form, keyList);

  const handleChange = (e) => {
    const updatedForm = setNestedValue(form, keyList, e.target.value);
    setForm(updatedForm);
  };

  return (
    <TextField
      label={label}
      value={currentValue ?? ''}
      onChange={handleChange}
      margin="normal"
    />
  );
};

// 示例调用:对应form.user.profile.name路径
// <RecursiveFormField form={form} setForm={setForm} keyList={['user', 'profile', 'name']} label="用户名" />

3. 动态遍历嵌套对象生成表单

如果表单结构是动态嵌套的,可通过递归遍历自动生成完整表单:

const RecursiveForm = ({ form, setForm, parentKeyList = [] }) => {
  return Object.entries(form).map(([key, value]) => {
    const currentKeyList = [...parentKeyList, key];
    
    // 当前值为对象时,递归生成子表单区域
    if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
      return (
        <div key={key} style={{ marginLeft: 20 }}>
          <h4>{key}</h4>
          <RecursiveForm form={value} setForm={setForm} parentKeyList={currentKeyList} />
        </div>
      );
    } 
    // 非对象值直接渲染输入框
    else {
      return (
        <RecursiveFormField
          key={key}
          form={form}
          setForm={setForm}
          keyList={currentKeyList}
          label={key}
        />
      );
    }
  });
};

// 根组件使用示例
const App = () => {
  const [form, setForm] = useState({
    user: {
      profile: {
        name: '',
        age: ''
      },
      contact: {
        email: '',
        phone: ''
      }
    }
  });

  return (
    <div style={{ padding: 20 }}>
      <h3>嵌套递归表单</h3>
      <RecursiveForm form={form} setForm={setForm} />
    </div>
  );
};

关键说明

  • 不可变更新:每一层对象都做浅拷贝,确保React能检测到状态变化,符合React状态更新规则。
  • 路径安全:处理了路径不存在的边界情况,避免出现Cannot set property of undefined错误。
  • 递归路径跟踪:通过parentKeyList拼接当前键,实现递归过程中对嵌套路径的完整追踪。

内容的提问来源于stack exchange,提问作者psygo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 16:03:11