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

React 18.2.0递归生成嵌套JSON表单遇无限重渲染问题求助

解决递归渲染嵌套JSON导致的"Too many re-renders"错误

问题原因

你当前代码的核心问题是在组件渲染周期中直接调用setDisplayForm:每次组件渲染时,都会执行setDisplayForm(builtForm)触发state更新;state更新又会触发组件重新渲染,如此循环往复,直接导致无限重渲染错误。另外,将JSX元素存储到state里也不符合React的最佳实践,React更推荐直接在渲染逻辑中生成UI。

解决方案

  1. 移除不必要的state:不需要把渲染结果存入state,直接在组件的return逻辑中调用递归函数生成UI。
  2. 优化递归判断逻辑:替换JSON.stringify的低效判断方式,直接通过类型检查和属性存在性判断来决定是否递归,提升性能。
  3. 用useMemo缓存渲染结果:针对深度嵌套的JSON,用useMemo缓存递归生成的JSX,避免每次渲染都重复执行递归逻辑。

修改后的代码

import { useState, useMemo } from 'react';
import reactLogo from './assets/react.svg';
import viteLogo from '/vite.svg';
import './App.css';

function App() {
  // 示例深度嵌套JSON,替换为你的实际数据
  const input = {
    label: "表单",
    properties: {
      name: {
        label: "姓名",
        type: "text"
      },
      contact: {
        label: "联系方式",
        properties: {
          phone: {
            label: "手机号",
            type: "tel"
          },
          email: {
            label: "邮箱",
            type: "email"
          }
        }
      }
    }
  };

  const displayProperties = useMemo(() => {
    const renderProperties = (properties) => {
      return (
        <>
          {Object.entries(properties).map(([key, value]) => {
            // 跳过非对象类型的非label属性,可根据需求调整
            if (key !== 'label' && typeof value !== 'object') return null;
            
            return (
              <div key={`${key}-${JSON.stringify(value)}`}>
                {key === 'label' && <span>{value}</span>}
                {typeof value === 'object' && value !== null && (
                  (value.properties || value.label) && renderProperties(value)
                )}
                {/* 根据type渲染对应输入字段 */}
                {key === 'type' && <input type={value} placeholder="请输入内容" />}
              </div>
            );
          })}
        </>
      );
    };
    return renderProperties(input);
  }, [input]);

  return <>{displayProperties}</>;
}

export default App;

关键优化点说明

  • 移除setDisplayForm和对应state:直接在useMemo中生成并缓存渲染结果,避免state更新触发的循环。
  • 高效递归判断:用typeof value === 'object' && value !== null判断对象类型,再检查是否包含properties或label属性,比JSON.stringify性能更优。
  • 合理的key值:用${key}-${JSON.stringify(value)}作为map的key,避免使用index导致的渲染异常。
  • 输入字段渲染逻辑:根据type属性渲染对应类型的输入框,匹配你"根据值渲染对应输入字段"的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:32:49