javascript - Reactjs 中的递归函数
问题描述
我正在使用递归函数制作动态菜单,并且我已经制作了菜单,并且它以正确的顺序显示,没有任何问题。
我从service.js文件中接收菜单数据,您可以在下面的代码沙箱示例中看到整个工作应用程序,
要求:
在这里,我需要找出最后一级菜单,并且需要将带有值的复选框分配为它们各自的 id {item.id}
。
例如:
对于第一个菜单,
-> [Checkbox with value as 1.1.1] One-One-One
-> [Checkbox with value as 1.1.2] One - one - two
-> [Checkbox with value as 1.1.3] One - one - three
对于第二个菜单二,
-> [Checkbox with value as 2.1] Two - one
.
.
.
对于第六个菜单六,
-> [Checkbox with value as 6] Six
我希望这一点很清楚,我需要找出递归的最后一层,并应该为其分配一个带有其 id 值的复选框。
请分叉提供的代码沙箱,并帮助我实现在最后一级制作复选框的结果。
可选要求: 如果可能的话,折叠对整个菜单都有效,请使其在每个单独的级别上以唯一的方式折叠。
但主要的重要要求是在菜单的最后一级制作一个复选框。提前非常感谢...
编辑:
正如 Crowder 评论的那样,我创建了删除 reactstrap 代码的片段,现在可以了,因为我需要显示复选框内联以保持子菜单的最新级别(最后一个子元素)。
const menuData = [
{
id: "1",
name: "One",
children: [
{
id: "1.1",
name: "One - one",
children: [
{ id: "1.1.1", name: "One - one - one" },
{ id: "1.1.2", name: "One - one - two" },
{ id: "1.1.3", name: "One - one - three" }
]
}
]
},
{
id: "2",
name: "Two",
children: [{ id: "2.1", name: "Two - one" }]
},
{
id: "3",
name: "Three",
children: [
{
id: "3.1",
name: "Three - one",
children: [
{
id: "3.1.1",
name: "Three - one - one",
children: [
{
id: "3.1.1.1",
name: "Three - one - one - one",
children: [
{ id: "3.1.1.1.1", name: "Three - one - one - one - one" }
]
}
]
}
]
}
]
},
{ id: "4", name: "Four" },
{
id: "5",
name: "Five",
children: [
{ id: "5.1", name: "Five - one" },
{ id: "5.2", name: "Five - two" },
{ id: "5.3", name: "Five - three" },
{ id: "5.4", name: "Five - four" }
]
},
{ id: "6", name: "Six" }
];
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
currentSelection: "",
menuItems: [],
isToggleOpen: false
};
}
componentDidMount() {
this.setState({ menuItems: menuData });
}
handleClick(id, evt) {
evt.preventDefault();
console.log("click handler called with", id);
this.setState({ currentSelection: id });
}
toggle() {
console.log(this.state);
this.setState({
isToggleOpen: !this.state.isToggleOpen
});
}
buildMenu(items) {
return (
<ul>
{items &&
items.map(item => (
<li key={item.id}>
<div>
{item.name}
{item.children && item.children.length > 0
? this.buildMenu(item.children)
: null}
</div>
</li>
))}
</ul>
);
}
render() {
return (
<div>
<h2>Click any of the below option</h2>
{this.state.menuItems &&
this.state.menuItems.map((item, index) => {
return (
<div key={index}>
{item.name}
{this.buildMenu(item.children)}
</div>
);
})}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/reactstrap/4.8.0/reactstrap.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/reactstrap/4.8.0/reactstrap.min.css" />
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.development.js"></script>
解决方案
buildMenu(items) {
return (
<ul>
{items &&
items.map((item, index) => (
<li key={item.id}>
<div>
{this.state.isToggleOpen}
{(item.children) ? 'Not Last': 'Here you can apply your check box'} //this check if item have children
<Button onClick={this.toggle.bind(this)}> {item.name} {index} </Button>
<Collapse isOpen={this.state.isToggleOpen}>
{item.children && item.children.length > 0
? this.buildMenu(item.children, index)
: null}
</Collapse>
</div>
</li>
))}
</ul>
);
}
现在渲染的第二种情况
<Button onClick={this.toggle.bind(this)}> {item.name}</Button>
检查项目是否有孩子
{(item.children) ? this.buildMenu(item.children) : 'Apply your checkbox here'}
完整代码
import React from "react";
import { render } from "react-dom";
import { loadMenu } from "./service";
import { Button, Collapse } from "reactstrap";
// const buildMenu = function buildMenu(items)
// const Menu = ({ items }) => buildMenu(items);
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
currentSelection: "",
menuItems: [],
isToggleOpen: false
};
}
componentDidMount() {
loadMenu().then(items => this.setState({ menuItems: items }));
}
handleClick(id, evt) {
evt.preventDefault();
console.log("click handler called with", id);
this.setState({ currentSelection: id });
}
toggle() {
console.log(this.state);
this.setState({
isToggleOpen: !this.state.isToggleOpen
});
}
buildMenu(items) {
return (
<ul>
{items &&
items.map(item => (
<li key={item.id}>
<div>
{this.state.isToggleOpen}
{(item.children) ? 'Not Last': 'Here you can apply your check box'}
<Button onClick={this.toggle.bind(this)}> {item.name} </Button>
<Collapse isOpen={this.state.isToggleOpen}>
{item.children && item.children.length > 0
? this.buildMenu(item.children)
: null}
</Collapse>
</div>
</li>
))}
</ul>
);
}
render() {
console.log(this.state.menuItems);
return (
<div>
<h2>Click any of the below option</h2>
{this.state.menuItems &&
this.state.menuItems.map((item, index) => {
return (
<div>
<Button onClick={this.toggle.bind(this)}> {item.name} </Button>
{(item.children) ? 'Not Last': 'Here you can apply your check box'}
<Collapse isOpen={this.state.isToggleOpen}>
{this.buildMenu(item.children)}
</Collapse>
</div>
);
})}
</div>
);
}
}
render(<App />, document.getElementById("root"));
推荐阅读
- reactjs - 使用打字稿反应组件子错误
- c++ - 通过自定义内核更改 cuda::GpuMat 值
- c - C 中的 printf("%s", &b) 打印目标字符串。为什么是 &b 而不是 b?
- regex - 转换 MMM。DD, YY 字符串到 date9。在SAS?
- arrays - 找到满足特定条件的数组中当前位置右边的所有元素?
- javascript - Express Validator:检查 Body Param 是否是给定对象的值之一
- javascript - 从回调中在主线程中抛出值错误
- c# - 提高 Xamarin 表单渲染性能
- r - 如何更改标题名称出现在 R 的森林图中?
- php - 如何使用 JSON 作为数据类型调试 jQuery.post()?