我想呈現使用ReactJS遞歸樹形結構。我很快就做了一個香草的例子(下圖)。現在我正在將它移植到React中,並且我一直在考慮它,但無法弄清楚如何去做。我已經將我的React示例包含在了vanilla之下。React JS遞歸樹
香草JS
createTree(data, isSub, lev) {
let level = lev || 0;
let html = (isSub) ? '<div class="filter-body">' : ''; // Wrap with div if true
if (isSub) { level++; }
for (let i = 0, len = data.length; i < len; i++) {
if (typeof(data[i].nested_values) === 'object') {
html += '<div class="filter-group level-' + level + '">';
if (isSub) {
html += '<div class="filter-heading">' + data[i].value + '</div>';
} else { // Submenu found, but top level list item.
html += '<div class="filter-heading">' + data[i].value + '</div>';
}
// Submenu found, call function recursively
html += this.createTree(data[i].nested_values, true, level);
html += '</div>';
} else {
html += '<span>' + data[i].value + '</span>' // No submenu, end of tree
}
}
html += (isSub) ? '</div>' : '';
return html;
}
ReactJS版本
我添加到陣列然後映射在其上,以輸出在我的渲染方法。我正在努力圍繞我的頭部的部分是如何注入遞歸調用..我覺得我非常接近,但一直在看它太久了,有什麼想法?
createTree(data, isSub, lev) {
let level = lev || 0;
for (let i in data) {
if (typeof(data[i].nested_values) === 'object') { // Sub array found, build structure
this.tmpArrB.push(
<div class={"filter-group level-" + (level)}>
<div class="filter-heading">{data[i].value}</div>
{this.createTree(data[i].nested_values, true, level)} // How to do this properly?
</div>
);
} else { // No submenu, bottom of tree
this.tmpArrB.push(
<span key={i}>
{data[i].value}
</span>);
}
}
this.tmpArr.push(<div className='filter-body open'>{this.tmpArrB}</div>);
}
更新版本(工作)
createSelectionHierarchy(data, isSub, level = 1) {
let children = [];
if (isSub) { level++; }
for (let i = 0, len = data.length; i < len; i++) {
if (typeof(data[i].nested_values) === 'object') { // Sub array found, build structure
children.push(
<FilterItem key={i} data={data[i]} level={level}>
{this.createSelectionHierarchy(data[i].nested_values, true, level)}
</FilterItem>
);
} else { // No submenu, bottom of tree
children.push(
<span key={i}>
{data[i].value}
</span>);
}
}
return children;
}
虛擬JSON
{
"possible_values": [{
"value": "Fruit",
"occurrence_count": 5,
"nested_values": [{
"value": "Berries",
"occurrence_count": 3,
"nested_values": [{
"value": "Strawberry",
"occurrence_count": 1
}, {
"value": "Blackberry",
"occurrence_count": 1
}, {
"value": "Raspberry",
"occurrence_count": 1
}, {
"value": "Redcurrant",
"occurrence_count": 1
}, {
"value": "Blackcurrant",
"occurrence_count": 1
}, {
"value": "Gooseberry",
"occurrence_count": 1
}, {
"value": "Cranberry",
"occurrence_count": 1
}, {
"value": "Whitecurrant",
"occurrence_count": 1
}, {
"value": "Loganberry",
"occurrence_count": 1
}, {
"value": "Strawberry",
"occurrence_count": 1
}]
}, {
"value": "Tropical",
"occurrence_count": 2,
"nested_values": [{
"value": "Pineapple",
"occurrence_count": 1
}, {
"value": "Mango",
"occurrence_count": 1
}, {
"value": "Guava",
"occurrence_count": 1
}, {
"value": "Passion Fruit",
"occurrence_count": 1
}, {
"value": "Dragon Fruit",
"occurrence_count": 1
}]
}]
}, {
"value": "Vegetable",
"occurrence_count": 2,
"nested_values": [{
"value": "Potato",
"occurrence_count": 3
}, {
"value": "Leek",
"occurrence_count": 3
}, {
"value": "Onion",
"occurrence_count": 3
}, {
"value": "Sprout",
"occurrence_count": 3
}, {
"value": "Carrot",
"occurrence_count": 3
}, {
"value": "Runner Bean",
"occurrence_count": 3
}, {
"value": "Swede",
"occurrence_count": 3
}, {
"value": "Turnip",
"occurrence_count": 3
}, {
"value": "Parsnip",
"occurrence_count": 3
}, {
"value": "Kale",
"occurrence_count": 3
}, {
"value": "Spinach",
"occurrence_count": 3
}, {
"value": "Artichoke",
"occurrence_count": 3
}, {
"value": "Broad Bean",
"occurrence_count": 3
}, {
"value": "French Bean",
"occurrence_count": 3
}, {
"value": "Brocolli",
"occurrence_count": 3
}, {
"value": "Cauliflower",
"occurrence_count": 3
}, {
"value": "White Cabbage",
"occurrence_count": 3
}, {
"value": "Red Cabbage",
"occurrence_count": 3
}, {
"value": "Savoy Cabbage",
"occurrence_count": 3
}, {
"value": "Corn",
"occurrence_count": 3
}, {
"value": "Courgette",
"occurrence_count": 3
}, {
"value": "Mange Tout",
"occurrence_count": 3
}, {
"value": "Sweet Potato",
"occurrence_count": 3
}, {
"value": "Pak Choi",
"occurrence_count": 3
}]
}]
}
這取決於你想要的輸出。事實上,您將React元素添加到數組會使事情變得複雜。理想情況下,該函數只是返回一個元素。 –
@FelixKling完全同意你的看法。他也可以利用道具和compo生命週期的概念。 –
這個數組的原因是因爲我想要嵌套可切換的div有更好的方式 - 首先得到這個工作然後重構 – Zinc