我正在编写一个反应应用程序,用于从嵌套对象数组中打印树视图。每个节点都应该是可折叠的(默认情况下是打开的)。节点可以具有任意数量的子节点。以下是我想要实现的一个示例:
我正在收集数组中的所有节点组件,然后在render方法中访问该集合。现在,所有节点组件都以相同的层次结构打印,因为它们没有相互嵌套。在下面的代码中,如何在<PrintNode treeData={obj}
数组中添加<PrintNode treeData={obj} hasChildNodes={true} />
作为treeToRender
的孩子?
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
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>
);
}
}
请注意,每个JSX元素都是一个对象,而不是一个可以轻松操作的字符串。
此外我收到错误“数组或迭代器中的每个子节点都应该有一个唯一的”key“prop。检查App的渲染方法。”即使我已经为PrintNode添加了密钥。为什么会这样?
这是fiddle。
答案 0 :(得分:4)
这是一个更新的解决方案。我希望这有助于您了解如何递归构建JSX对象。
我也提供了一个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'
}
];