简体   繁体   English

将JSX元素作为数组内另一个JSX元素的子元素推送(ReactJS)

[英]Push JSX element as a child of another JSX element inside an Array (ReactJS)

I am writing a react app to print a tree-view from an array of nested objects. 我正在编写一个反应应用程序,以从嵌套对象数组中打印树状视图。 Each node should be collapsible (open by default). 每个节点应可折叠(默认情况下处于打开状态)。 A node may have any number of child nodes. 一个节点可以具有任意数量的子节点。 Here is a sample of what I am trying to achieve: 这是我要达到的目标的一个示例:

树视图

I am collecting all node components inside an array and then accessing that collection in render method. 我正在收集数组中的所有节点组件,然后在render方法中访问该集合。 Right now all node components are printed at same heirarchy as they are not nested in each other. 现在,所有节点组件都以相同的层次结构打印,因为它们彼此之间并不嵌套。 In the code below, how can I add <PrintNode treeData={obj} as a child of <PrintNode treeData={obj} hasChildNodes={true} /> in the treeToRender array? 在下面的代码中,如何在<PrintNode treeData={obj}添加<PrintNode treeData={obj}作为<PrintNode treeData={obj} hasChildNodes={true} />treeToRender

App.js: App.js:

import React from 'react';
import PrintNode from './components/PrintNode';

export default class App extends React.Component {
  data = [ // this data will come from another file in real app
    {
      text: 'Parent 1',
      nodes: [
        {
          text: 'Child 1',
          nodes: [
            {
              text: 'Grandchild 1'
            },
            {
              text: 'Grandchild 2'
            }
          ]
        },
        {
          text: 'Child 2'
        }
      ]
    },
    {
      text: 'Parent 2'
    },
    {
      text: 'Parent 3'
    },
    {
      text: 'Parent 4'
    },
    {
      text: 'Parent 5'
    }
  ];

  treeToRender = [];

  getNextNode(nextData) {
    let key = 0;
    for (let i = 0; i < nextData.length; i++) {
      let obj = nextData[i];
      if (!obj.nodes) {
        this.treeToRender.push(<PrintNode treeData={obj} />)
        key++;
      }
      else {
        this.treeToRender.push(<PrintNode treeData={obj} hasChildNodes={true} />)
        key++;
        this.getNextNode(obj.nodes);
      }
    }
    return this.treeToRender;
  }

  render() {
    return (
      <div className="app-container">
        {this.getNextNode(this.data)}
      </div>
    );
  }
}

PrintNode.js PrintNode.js

import React from 'react';

export default class PrintNode extends React.Component {
    render() {
        let nodeToRender = '';
        if (this.props.hasChildNodes) {
            nodeToRender = <div className="has-child">{this.props.treeData.text}</div>
        }
        else {
            nodeToRender = <div>{this.props.treeData.text}</div>
        }
        return (
            <div>
                <div>{this.props.treeData.text}</div>
            </div>
        );
    }
}

Please note that each JSX element is an object, not a string which can be easily manipulated. 请注意,每个JSX元素都是一个对象,而不是一个易于操作的字符串。

Also I am getting error "Each child in an array or iterator should have a unique "key" prop. Check the render method of App." 我也收到错误消息“数组或迭代器中的每个子代都应具有唯一的“键”属性。请检查App的渲染方法。” even though I have added key to PrintNode. 即使我已将密钥添加到PrintNode。 Why is this happening? 为什么会这样呢?

Here is the fiddle . 这是小提琴

Here is an updated solution for. 这是一个更新的解决方案。 I hope this helps you understand how to recursively build JSX objects. 我希望这可以帮助您了解如何以递归方式构建JSX对象。

I've provided a Codepen as well for you to look at so that you can see the working code. 我还提供了一个Codepen供您查看,以便您可以查看工作代码。

function createTree(data) {
    return (
        <ul>
            {
                data.map((node) => {
                    return createNode(node);
                })
            }
        </ul>
    );
}

function createNode(data) {
    if (data.nodes) {
        return (
      <li>
        <PrintNode text={ data.text }>{createTree(data.nodes)}</PrintNode>
      </li>
    );
    } else {
        return <PrintNode text={ data.text } />
    }
}

const PrintNode = (props) => {
    return <li>{ props.text }{ props.children }</li>
};

const App = (props) => {
    return createTree(props.data);
}

ReactDOM.render(<App data={ data } />, document.getElementById("app"));

const data = [
    {
        text: 'Parent 1',
        nodes: [
            {
                text: 'Child 1',
                nodes: [
                    {
                        text: 'Grandchild 1'
                    },
                    {
                        text: 'Grandchild 2'
                    }
                ]
            },
            {
                text: 'Child 2'
            }
        ]
    },
    {
        text: 'Parent 2'
    },
    {
        text: 'Parent 3'
    },
    {
        text: 'Parent 4'
    },
    {
        text: 'Parent 5'
    }
];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM