Reactjs 中的递归函数 [英] Recursive function in Reactjs

查看:40
本文介绍了Reactjs 中的递归函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用递归函数制作动态菜单,并且我已经制作了菜单并且它以正确的顺序显示,没有任何问题.

我从 service.js 文件接收菜单数据,您可以在下面的代码沙箱示例中看到整个工作应用程序,

<块引用>

https://codesandbox.io/s/reactstrap-accordion-3uoz9

要求:

在这里,我需要找出最后一级菜单,并需要为复选框分配值作为其各自的 ID {item.id}.

例如:

对于第一个菜单一个

 ->[复选框值为 1.1.1] 一对一->[复选框值为 1.1.2] 一 - 一 - 二->[复选框的值为 1.1.3] 一 - 一 - 三

对于第二个菜单两个

 ->[复选框的值为 2.1] 二 - 一

.

.

.

对于第六个菜单六个

 ->[复选框的值为 6] 六

我希望这一点很清楚,我需要找出递归中的最后一级,并且应该为其分配一个复选框,其中包含它们的 id 值.

请fork提供的代码沙箱,帮我实现最后一层checkbox的结果.

可选要求:如果可能的话,折叠可以同时对整个菜单起作用,请使其在每个单独的级别以独特的方式折叠.

但主要的重要要求是在菜单的最后一级制作一个复选框.提前致谢...

正如 Crowder 所评论的,我已经创建了删除 reactstrap 代码的片段,现在可以了,因为我需要将复选框内联显示到子菜单的最后一级(最后一个子元素).

const menuData = [{编号:1",name: "一个",孩子们: [{编号:1.1",name: "一-一",孩子们: [{ id: "1.1.1", name: "一-一-一" },{ id: "1.1.2", name: "一-一-二" },{ id: "1.1.3", name: "一-一-三" }]}]},{编号:2",name: "两个",孩子:[{ id:2.1",名称:二-一"}]},{编号:3",name: "三",孩子们: [{编号:3.1",name: "三一",孩子们: [{id: "3.1.1",name: "三一一",孩子们: [{id: "3.1.1.1",名称:三一一一",孩子们: [{ id: "3.1.1.1.1", name: "三一一一一一" }]}]}]}]},{ id: "4", name: "4" },{编号:5",name: "五",孩子们: [{ id: "5.1", name: "五-一" },{ id: "5.2", name: "五-二" },{ id: "5.3", name: "五-三" },{ id: "5.4", name: "五 - 四" }]},{ id: "6", name: "6" }];类 App 扩展了 React.Component {构造函数(道具){超级(道具);this.state = {当前选择:",菜单项:[],isToggleOpen: 假};}componentDidMount() {this.setState({ menuItems: menuData });}句柄点击(id,evt){evt.preventDefault();console.log("点击处理程序调用", id);this.setState({ currentSelection: id });}切换(){控制台日志(这个状态);this.setState({isToggleOpen: !this.state.isToggleOpen});}构建菜单(项目){返回 (<ul>{项目&&items.map(item => (<li key={item.id}><div>{项目名称}{item.children &&item.children.length >0?this.buildMenu(item.children): 空值}

))});}使成为() {返回 (<div><h2>单击以下任一选项</h2>{this.state.menuItems &&this.state.menuItems.map((item, index) => {返回 (<div key={index}>{项目名称}{this.buildMenu(item.children)}

);})}

);}}ReactDOM.render(, 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) {返回 (<ul>{项目&&items.map((item, index) => (<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} {index} </Button><Collapse isOpen={this.state.isToggleOpen}>{item.children &&item.children.length >0?this.buildMenu(item.children, index): 空值}</收起>

))});}

现在是渲染的第二种情况

检查项目是否有孩子

{(item.children) ?this.buildMenu(item.children) : '在此处应用您的复选框'}

完整代码

从react"导入React;从react-dom"导入{渲染};import { loadMenu } from "./service";import { Button, Collapse } from "reactstrap";//const buildMenu = function buildMenu(items)//const Menu = ({ items }) =>构建菜单(项目);类 App 扩展了 React.Component {构造函数(道具){超级(道具);this.state = {当前选择:",菜单项:[],isToggleOpen: 假};}componentDidMount() {loadMenu().then(items => this.setState({ menuItems: items }));}句柄点击(id,evt){evt.preventDefault();console.log("点击处理程序调用", id);this.setState({ currentSelection: id });}切换(){控制台日志(这个状态);this.setState({isToggleOpen: !this.state.isToggleOpen});}构建菜单(项目){返回 (<ul>{项目&&items.map(item => (<li key={item.id}><div>{this.state.isToggleOpen}{(item.children) ?'Not Last': '在这里你可以应用你的复选框'}<Button onClick={this.toggle.bind(this)}>{item.name} <Collapse isOpen={this.state.isToggleOpen}>{item.children &&item.children.length >0?this.buildMenu(item.children): 空值}</收起>

))});}使成为() {控制台日志(this.state.menuItems);返回 (<div><h2>单击以下任一选项</h2>{this.state.menuItems &&this.state.menuItems.map((item, index) => {返回 (<div><Button onClick={this.toggle.bind(this)}>{item.name} {(item.children) ?'Not Last': '在这里你可以应用你的复选框'}<Collapse isOpen={this.state.isToggleOpen}>{this.buildMenu(item.children)}</收起>

);})}

);}}render(, document.getElementById("root"));

I am making dynamic menus using a recursive function and I have already made the menus and it display in the right order without any issues.

And I receive the data for menu from service.js file and you can see the entire working application in the below code sandbox example,

https://codesandbox.io/s/reactstrap-accordion-3uoz9

Requirement:

Here I am in the need to find out the last level of menus and need to assign checkbox with value as their respective id {item.id}.

Eg:

For First menu one,

 -> [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

For Second menu two,

 -> [Checkbox with value as 2.1] Two - one

.

.

.

For sixth menu six,

 -> [Checkbox with value as 6] Six

I hope the point is clear that I need to find out the last level in recursion and should assign a checkbox to it with the value of their id.

Please fork the code sandbox provided and help me to achieve the result of making the checkbox at the last level.

Optional requirement: The collapse is working for whole menus at once if possible please make it collapse at each individual level in unique.

But the main important requirement is to make a checkbox at the last level of menus. A big thanks in advance...

Edit:

As commented by Crowder, I have created the snippet removing reactstrap code and it is okay now because I am in the need of displaying checkbox inline to laste level of submenus (last children elements).

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>
    );
  }

Now second case on render

<Button onClick={this.toggle.bind(this)}> {item.name}</Button>

Check if item have children

{(item.children) ? this.buildMenu(item.children) : 'Apply your checkbox here'}

Full Code

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 中的递归函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆