3

我有一个来自 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>
  )

提前致谢。

4

2 回答 2

2

ReactJS 是一个基于组件的库,用于生成 UI。因此,从组件的角度考虑,您的数据是一个组,该组又将包含一个表达式和其他与其类似的组。分解它,我们可以形成三个组件:

  1. Expression用于简单地呈现组中的表达式。
  2. Group用于渲染组。
  3. Groups用于为数据中的其他组提取然后渲染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...in并且map可以用for循环替换。 示例渲染

于 2019-10-18T14:38:10.030 回答
1

您的map()回调没有return值,但在第二个if语句中,您将返回数组,因此[undefined, undefined, ...]当您递归到 each 时,您最终会得到groups

要修复您的解决方案,请同时更改您的.map()to.forEach()并删除return关键字 before 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>
  );
}

请注意,使用indexas是一种模式。理想情况下,如果您提供了一个唯一 ID,您将希望使用一个唯一 ID。请参阅ReactJS :在数组元素中提供键的最佳方法是什么,以获取更多信息。

于 2019-10-18T13:06:56.057 回答