ABOUT ME

-

  • [ Vite + React ] React Router 사용 및 관리
    Front/React 2025. 5. 1. 16:19
    반응형

    기존에 Router를 사용할때 Navigator를 활용해서 해당 메뉴를 누르면

    Navigator로 이동을 시키는 방법으로 router를 사용했었는데

    이 경우 메뉴를 하나 추가할때마다 여러 파일에서 추가적으로 작업을 해주어야했기에 좀 더 편하게 관리하고자 했다.

     

    이번에는 navigator로 이동을 하는 것이 아닌 Link를 활용하여 a 태그로 이동이 되도록 처리하고,

    routes와 router도 자동으로 만들어지도록 하여

    좀 더 메뉴를 쉽게 관리할 수 있도록 바꿔보았다.

     

    기존의 react-router는 그대로 사용한다.

    npm install react-router-dom

    Router Type

    router를 좀 더 편하게 사용하기위해 타입을 커스텀을 해준다.

    기존의 RouteObject를 활용하여 router 할 수 있지만,

    최대한 편하게 활용하기 위해서 RouteMeta타입을 추가로 만들어서 사용했다.

    title과, icon, hidden으로 해당 경로의 메뉴명, 그리고 아이콘, 그리고 사용여부를 넣어 이 값으로 쉽게 관리 할 수 있도록 처리

    import {RouteObject} from "react-router-dom";
    import React from "react";
    
    export type RouteMeta = {
        title?: string
        icon?: React.FC<React.SVGProps<SVGSVGElement>>
        hidden?: boolean
    }
    
    export type CustomRouteObject = RouteObject & {
        meta?: RouteMeta
        children?: CustomRouteObject[]
    };

    Router

    router를 사용할 때 메뉴를 관리하는 파일을 하나 만들어준다.

    router 폴더 안에 index.tsx와 menu.tsx 파일을 만들어서

    index는 router경로를 세팅하고, menu에서는 사용할 메뉴를 추가 및 삭제를 할 수 있도록 구현

    -> 이렇게 하면 나중에 메뉴를 바꿔야한다면 menu 파일에서 메뉴만 수정하면 알아서 메뉴가 만들어진다.

     

    index.tsx

    index.tsx 에서 router를 설정하는데 이때

    타입은 key: value 형태로 하며

    path는 해당 경로

    element는 해당 path에 들어오면 <Layouts/> 를 보여주며 Layout 컴포넌트는 전체 레이아웃을 잡는 파일이다.

    // 📁 router/index.ts
    import {Layouts} from '@/layouts';
    import {menuRoutes} from './menu';
    import {CustomRouteObject} from "src/types";
    
    const routes: { [key: string]: CustomRouteObject } = {
        menu: {
            path: '/',
            element: <Layouts />,
            children: menuRoutes,
        },
    };
    
    export default routes;

     

    children에는 menu들을 가져와서 넣어주는데 여기서 menu도 같은 타입으로 되어있고

    meta: 안에 해당 필요한 값들을 넣어준다.

    import {SkinCare} from '@/pages/skin-care';
    import {Navigate} from 'react-router-dom';
    import {CustomRouteObject} from "src/types";
    import {Home} from "@/pages/home";
    
    export const menuRoutes: CustomRouteObject[] = [
        {
            index: true,
            element: <Home/>,
            meta: {
                hidden: true,
            },
        },
        {
            path: 'home',
            element: <Navigate to="/" replace />,
            meta: {
                title: 'home',
            },
        },
        {
            path: 'home2',
            element: <Home />,
            meta: {
                title: 'home2',
            },
        },
    ];

     


    Menus

    이제 메뉴들을 가져와서 화면에 뿌려주기만 하면된다.

    mene.tsx파일의 메뉴 router값들을 가져와서 

     

    Link태그로 생성해주며, meta에 있는 값들로 추가 처리를 해준다.

    hidden이 아닌 메뉴들만 가져오며,

    icon이 있을경우 icon 그리고 title을 넣어준다.

    import {Link, useLocation} from "react-router-dom";
    import {menuRoutes} from "@/router/menu";
    import {CustomRouteObject} from "src/types";
    import {Icon} from "@/components";
    import styled from "styled-components";
    
    const NavLayout = styled.nav`
        display: flex;
        align-items: center;
        gap: 10px;
    `
    export const Menu = () => {
        const location = useLocation();
    
        const renderMenu = (routes: CustomRouteObject[]) =>
            routes.map((route) => {
                if (route.meta?.hidden) return null;
                return (
                    <div key={route.path}>
                        <Link
                            to={route.path || "/"}
                            className={`menu-item ${location.pathname === route.path ? "active" : ""}`}
                        >
                            {route.meta?.icon && <Icon icon={route.meta.icon}/>}
                            <span>{route.meta?.title}</span>
                        </Link>
                        {route.children && <div className="sub-menu">{renderMenu(route.children)}</div>}
                    </div>
                );
            });
    
        return <NavLayout className="sidebar">{renderMenu(menuRoutes)}</NavLayout>;
    
    };

     

    그러면 화면에 이런식으로 a 태그로 메뉴가 만들어지고 

    해당 메뉴로 이동하면 해당 메뉴의 컴포넌트가 보여져야 하므로,

    보여지는 컴포넌트쪽에 추가적으로 main 컴포넌트에서

    Routes 와 Router는 메뉴를 만들때처럼 menu router값을 가져와서 해당 경로로 이동하면 설정해둔 element로 이동되도록 처리했다.

     

    import {Route, Routes} from "react-router-dom";
    import {menuRoutes} from "@/router/menu";
    
    export const Main = () =>
        <>
            <Routes>
                {menuRoutes.map((route, index) => (
                    <Route
                        key={index}
                        path={route.path || '/'}
                        element={route.element}
                    >
                        {route.children && route.children.map((child, childIndex) => (
                            <Route
                                key={childIndex}
                                path={child.path}
                                element={child.element}
                            />
                        ))}
                    </Route>
                ))}
            </Routes>
        </>

     

    그럼 해당 메뉴를 누르면 페이지가 이동되면서 해당 element가 화면에 보이는게 된다.

    728x90
    반응형