在React JS中呈现n级嵌套对象的最有效方法是什么?

时间:2019-10-18 12:06:02

标签: javascript reactjs recursion nested-object

我有一个来自API的数据,如下所示-

{
  "expression": [
    "a",
    "b"
  ],
  "groups": [
    {
      "expression": [

      ],
      "groups": [
        {
          "expression": [
            "c",
            "d"
          ],
          groups: null
        }
      ]
    },
    {
      "expression": [
        "p",

      ],
      groups: null
    }
  ]
}

我必须渲染“表达式”和“组”(也包括表达式和多个组)。构件是一个表达式。我们需要将嵌套表达式显示为组。

我尝试了递归函数调用,但是对于深度较大的对象而言,这样做效率不高。

这与我的审判类似-

let conditionStack = [];
  function parseInnerConditions(conditionObj) {
    if (conditionObj.expression) {
      conditionObj.expression.map((each, index) => {
        conditionStack = [
          ...conditionStack,
          <NewExpression key={index} conditionExpression={each} />, //renders an expression
        ];
      });
    }
    if (conditionObj.groups && conditionObj.groups.length) {
      return conditionObj.groups.map((child, index) => {
        conditionStack = [
          ...conditionStack,
          <ConditionGroup key={index}> // renders a block or group of expressions
            {parseInnerConditions(child)}
          </ConditionGroup>,
        ];
      });
    }
    return conditionStack;
  }

  return (
    <div>
    parseInnerConditions(conditionObject)
    </div>
  )

谢谢。

2 个答案:

答案 0 :(得分:1)

您的map()回调没有一个return值,但是在第二个if语句中,您将返回该数组,因此最终将得到{{1 }}递归到每个[undefined, undefined, ...]时。

要解决此问题,请将groups都更改为.map(),并在.forEach()之前删除return关键字。

这是一个更好的方法:

conditionObj.groups.map(...)

请注意,将function ConditionGroup ({ expression, groups }) { const conditionExpressions = useMemo( () => expression && expression.map( (value, index) => ( <NewExpression key={index} conditionExpression={value} /> ) ), [expression] ); const conditionGroups = useMemo( () => groups && groups.map( (value, index) => ( <ConditionGroup key={index} {...value} /> ) ), [groups] ); return ( <div> {conditionExpressions} {conditionGroups} </div> ); } 用作keyantipattern。理想情况下,如果您提供了一个唯一的ID,则希望使用该ID。有关更多信息,请参见ReactJS : What is the best way to give keys in array element

答案 1 :(得分:1)

ReactJS是用于生成用户界面的基于组件的库。因此,就组件而言,您的数据是一个组,该组又将包含一个表达式和其他类似其自身的组。分解为以下三个部分:

  1. Expression用于仅在一个组中呈现表达式。
  2. Group用于渲染组。
  3. Groups用于提取Group组件,然后渲染数据中的其他 group

这是示例代码:

Index.js这是从API获取数据的文件。

import React from "react";
import Group from "./Group";

const data = {
  expression: ["a", "b"],
  groups: [
    {
      expression: [],
      groups: [{ expression: ["c", "d"], groups: null }]
    },
    {
      expression: [],
      groups: [
        { expression: ["e", "f"], groups: null },
        { expression: ["g", "h"], groups: null }
      ]
    },
    {
      expression: ["p"],
      groups: null
    }
  ]
};
const stage = 1;
const Main = () => {
  return (
    <div>
      <Group data={data} stage={stage} />
    </div>
  );
};

export default Main;

Group.js用于渲染组。

import React from "react";
import Expression from "./Expressions";
import Groups from "./Groups";

const populateGroup = (data, stage) => {
  const HTML = [];
  for (const x in data) {
    if (x === "expression") {
      HTML.push(<Expression expression={data[x]} />);
    }
    if (x === "groups") {
      HTML.push(<Groups data={data[x]} stage={stage} />);
    }
  }
  return HTML;
};

const Group = ({ data, stage }) => {
  return (
    <div>
      <p>{`Group @ Stage ${stage}`}</p>
      <ol className="Group">{populateGroup(data, stage + 1).map(el => el)}</ol>
    </div>
  );
};

export default Group;

Expression.js用于仅在一个组中呈现表达式。

import React from "react";

const Expression = ({ expression }) => {

return (
    <div className="expression">
      {expression.map(term => (
        <h3 style={{ display: "inline" }}>{term}</h3>
      ))}
    </div>
  );
};

export default Expression;

Groups.js用于提取然后渲染Group组件。

import React from "react";
import Group from "./Group";

const Groups = ({ data, stage }) => {

  if (data === null) return <span></span>;

  return (
    <div className="GroupsSection">
      {data.map((section, i) => (
        <Group key={i} data={section} stage={stage} />
      ))}
    </div>
  );
};

export default Groups;

性能使用这种基于组件的方法,可以对数据进行分块处理,这将提高性能,从而获得更好的结果for...inmap可以替换为for循环。 Sample Render