개발공부 임고미

[React] Antd menu 활용 본문

리액트/앤트디(Antd)

[React] Antd menu 활용

임고미 2020. 12. 9. 14:57
728x90
300x250
// base
import React, { useState, useEffect, ReactNode } from 'react';
import { useHistory } from 'react-router';

// packages
import { Menu } from 'antd';

import {
  HomeOutlined,
  FileDoneOutlined,
  BarChartOutlined,
  TeamOutlined,
} from '@ant-design/icons';

// modules
import { Link } from 'react-router-dom';

export const MainNav = () => {
  const roots = ['sub1', 'sub2', 'sub3', 'sub4'];
  const userMenus = [
    {
      key: 'item1',
      name: '서브메뉴1',
      root: 'sub1',
      sub: [
        {
          key: 'content1',
          name: '콘텐츠1',
        },
        {
          key: 'content2',
          name: '콘텐츠2',
        },
      ],
    },
    {
      key: 'item2',
      name: '서브메뉴2',
      root: 'sub2',
    },
     {
      key: 'item3',
      name: '서브메뉴3',
      root: 'sub3',
    },
      {
      key: 'item4',
      name: '서브메뉴4',
      root: 'sub4',
    },
  ];

  const [openKeys, setOpenkeys] = useState>(); //펼쳐져 있을 메뉴
  const [selectedKeys, setSelectedKeys] = useState(); //키

  const history = useHistory();
 
  useEffect(() => {
    const pathname = history.location.pathname; // 현재 위치
    const splitPathName = pathname.split(/(?=\/)/g); // '/'기준으로 위치 나누기
    
    const openKey =
      splitPathName.length === 3
        ? [`${splitPathName[0]}`, `${splitPathName[0]}${splitPathName[1]}`] //오픈된 메뉴가 2단의 메뉴인 경우
        : [`${splitPathName[0]}`]; //1단만 열려 있는경우

    setOpenkeys(openKey);
    setSelectedKeys([pathname]);
  }, [history.location.pathname]);

  if (!userMenus || !selectedKeys) {
    return <div />;
  }

  

  const menuTypee = {
    sub1: {
      icon: <HomeOutlined />,
      title: '루트1',
    },
    sub2: {
      icon: <TeamOutlined />,
      title: '루트2',
    },
    sub3: {
      icon: <FileDoneOutlined />,
      title: '루트3',
    },
    sub4: {
      icon: <BarChartOutlined />,
      title: '루트4',
    },
  };

  return (
    <Menu
      className="main-nav"
      theme="dark"
      mode="inline"
      openKeys={openKeys}
      selectedKeys={selectedKeys}
      onOpenChange={(openKeys) => setOpenkeys(openKeys)}
    >
      {roots.map((root) => {
        if (!menuType[root]) {
          return null;
        }

        return (
          <Menu.SubMenu
            key={`/${root}`}
            title={
              <>
                {menuType[root].icon}
                <span className="main-nav">
                  {menuType[root].title}
                </span>
              </>
            }
          >
            {userMenus &&
              userMenus
                .filter((item) => item.root === root)
                .map((item, idx) => {
                  const pathname = `/${item.root}/${item.key}`;
                  if (item.sub) {
                    return (
                      <Menu.SubMenu
                        key={pathname}
                        title={
                          <>
                            <span className="main-nav__submenu">
                              {item.name}
                            </span>
                          </>
                        }
                      >
                        {item.sub.map((item_sub) => {
                          const pathname_sub = `${pathname}/${item_sub.key}`;

                          return (
                            <Menu.Item key={pathname_sub}>
                              <Link to={pathname_sub}>{item_sub.name}</Link>
                            </Menu.Item>
                          );
                        })}
                      </Menu.SubMenu>
                    );
                  } else {
                    return (
                      <Menu.Item key={pathname}>
                        <Link to={pathname}>{item.name}</Link>
                      </Menu.Item>
                    );
                  }
                })}
          </Menu.SubMenu>
        );
      })}
    </Menu>
  );
};
728x90
300x250
Comments