Recursive function in Reactjs

这一生的挚爱 提交于 2020-03-20 06:53:26

问题


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>

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

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


来源:https://stackoverflow.com/questions/60600098/recursive-function-in-reactjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!