preface

As the sidebar grows more and more… The three-level menu, which was not considered, also needs to be taken into account;

You start with a manual map to go through the components, the group IDS that are associated with them and so again it’s easy to say children returns a value;

Take a look if you’re interested

Analysis of the required

The routing specifications are uniform and the routing hierarchy is variable. Sub-items with ICONS are allowed to automatically generate corresponding menu bar data

Routes are written as static routing table postures.

Const RouterTree = [{key: 'g0', icon: 'dashboard', text: 'data ', path: '/dashboard', children: [{key: '1', text: 'data overview, path:'/dashboard/monitor,}, {key: '2', the text: 'day live on live, path:'/dashboard/dau,}, {key: '3', the text: 'Retention ', path: '/dashboard/retentio.... omit N multiple specificationsCopy the code

Train of thought

My idea is to recurse directly and write it as a functional component.

Style uses ANTD;

rendering

Code implementation and usage

Recursive component functions

The performance time consuming

Based on my project, there are about 20 of them, the deepest is layer 3, using console.time() to run, the performance is good

First traversal of the tree:0.782958984375Ms traverses the tree for the second time:0.385009765625ms
Copy the code

The callback is mainly passed a handler function, such as jump handling, etc

// Recursive sidebar
  sidebarTree = (RouterTree, callback) = > {
    // Check whether the array is valid and the length is greater than 0.
    let isValidArr = value= > value && Array.isArray(value);
    let isValidArrChild = value= >
      value && value.children && Array.isArray(value.children) && value.children.length > 0;
    function recursive(Arr) {
      if (isValidArr(Arr)) {
        return Arr.map(ArrItem= > {
          if (isValidArrChild(ArrItem)) {
            return (
              <SubMenu
                key={ArrItem.key}
                title={
                  <div>
                    {ArrItem.icon ? <Icon type={ArrItem.icon} theme="outlined" /> : null}
                    <span>{ArrItem.text}</span>
                  </div>
                }
              >
                {recursive(ArrItem.children)}
              </SubMenu>
            );
          }
          return (
            <Item key={ArrItem.key} onClick={() => callback(ArrItem)}>
              {ArrItem.icon ? <Icon type={ArrItem.icon} theme="outlined" /> : null}
              <span>{ArrItem.text}</span>
            </Item>
          );
        });
      }
    }
    return recursive(RouterTree);
  };

Copy the code

callback(I have my jump function here)


  // Route jump
  gotoUrl = item= > {
    const { history, location } = this.props;
    this.setState({
      selectedKeys: [item.key],
    });
    if (location.pathname === item.path) {
      return;
    } else{ history.push(item.path); }};Copy the code

usage

// I maintain the static route myself
import RouterTree, { groupKey, findKey } from './RouterTree';

<Sider
    breakpoint="lg"
    collapsed={collapsed}
    width="160"
    style={{ backgroundColor:` ${theme ? '#001529' : '#fff` '}}}onCollapse={this.toggleCollapsed}
    >
    <Logo collapsed={collapsed} mode={mode} theme={theme} />
    <Menu
      inlineIndent={12}
      subMenuOpenDelay=0.3} {
      theme={theme ? 'dark' : 'light'}
      openKeys={openKeys}
      mode="inline"
      selectedKeys={selectedKeys}
      onOpenChange={this.onOpenChange}
    >
      {this.sidebarTree(RouterTree, this.gotoUrl)}
    </Menu>
    </Sider>

Copy the code

conclusion

If there is something wrong, please leave a message and correct it in time. Thank you for reading.