Reactjs 中的递归函数
Posted
技术标签:
【中文标题】Reactjs 中的递归函数【英文标题】:Recursive function in Reactjs 【发布时间】:2020-06-21 07:35:08 【问题描述】:我正在使用递归函数制作动态菜单,并且我已经制作了菜单,并且它以正确的顺序显示,没有任何问题。
我从 service.js 文件中收到菜单数据,您可以在下面的代码沙箱示例中看到整个工作应用程序,
https://codesandbox.io/s/reactstrap-accordion-3uoz9
要求:
这里我需要找出最后一级菜单,并需要将复选框分配为它们各自的 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 值的复选框。
请fork提供的代码沙箱,帮我实现最后一层checkbox的效果。
可选要求: 如果可能的话,折叠会同时对整个菜单起作用,请使其在每个单独的级别上以唯一的方式折叠。
但主要的重要要求是在菜单的最后一级制作一个复选框。 提前非常感谢...
编辑:
正如 Crowder 所评论的,我已经创建了 sn-p 删除 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>
【问题讨论】:
@TJCrowder,如果我没记错的话,这就是 react OP 将如何发布问题并提供指向代码沙箱的链接,这是我在 Stack Overflow 中看到的最大内容。即使是有角度的,他们也提供Stackblitz 链接.. 甚至人们只在此类链接中要求最小可复制链接。主要是反应。 我不确定谁投了反对票,尽管我的问题很清楚并且我已经尝试了最大的尝试.. 在哪里你需要得到id
?我看不出你打算在哪里使用它。
@TJCrowder,我无法找到在代码 sn-p 中创建两个不同文件的方法,例如 index.js
和 service.js
,因为它一次只允许一个文件.. 可能我得到你的帮助来做这件事..
@TJCrowder,我已经对我真正需要的东西做了一个简单的sn-p。所以你现在能帮我吗..在我需要分配的最后一个级别之前以相应 id 作为值的复选框..
【参考方案1】:
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"));
【讨论】:
让我知道将我的答案投票为 (item.children) 的原因? 'Not Last': 'Here you can apply your check box' 将检查项目是否还有其他子项,如果没有,则用户可以应用复选框。只是无缘无故地投票不是一种方法。如果有任何问题,我将不胜感激。谁投了反对票。 @TestUser 我没有添加复选框,但您可以使用代码获取最后一个元素。只需将您的 buildMenu 方法替换为上面的方法即可。并添加 (item.children) ? this.buildMenu(item.children) : 'Apply your checkbox here' 在渲染中使用的 它不适用于第一级,例如,four
和 six
..
我需要为最后一项分配复选框,就像我在左侧给出的问题 [Checkbox with value as 1.1.1] One-One-One
复选框和右侧的相应文本,复选框值为 id
但是不幸的是,您的解决方案不能满足我的需要。无论如何,非常感谢您的帮助和时间..以上是关于Reactjs 中的递归函数的主要内容,如果未能解决你的问题,请参考以下文章