개인 프로젝트를 진행하던 도중 타입스크립트에서 리액트 라우터 사용하는 법을 기억하기위해 이 글을 작성한다.
우선 프로젝트의 구성은 이렇게 된다.
// App.tsx
const router = createBrowserRouter([
{
path: '/',
element: <Root />,
errorElement: <NotFound />,
children: [
{ index: true, element: <Home /> },
{ path: 'login', element: <Login /> },
{ path: 'write', element: <Write /> },
{ path: 'board', element: <Board /> },
],
},
]);
const App: React.FC = () => {
return (
<>
<RouterProvider router={router} />
</>
);
};
App.tsx 파일은 이렇게 구성되어있다.
createBrowserRouter 메서드를 통해 라우터를 구성한다.
path
로 경로를 구성하고 element
에 전달할 컴포넌트를 넣어준다.
// Root.tsx
import Header from './Header';
import { Outlet } from 'react-router-dom';
const Root = () => {
return <>
<Header/>
<main>
<Outlet/>
</main>
</>
};
export default Root;
레이아웃을 구성하기위해 Root 컴포넌트를 별도로 만들었고,
그 안에 Header
컴포넌트와 children 역할을 하는 Outlet
을 사용하였다.
RouterProvider
에 router
를 넘겨주면 root경로인 Root
컴포넌트만 출력된다.
Root
컴포넌트를 출력하는 이유는 레이아웃화 하기 위해서이다.
Outlet
영역에 각각의 Route들에 매칭시켜놓은 element
가 렌더링된다.
import React from 'react';
import styles from './Header.module.css';
import { Link, NavLink } from 'react-router-dom';
type Props = {};
const Header = (props: Props) => {
return (
<>
<header>
<h1>
<Link to='/'>게시판</Link>
</h1>
<nav>
<ul className={styles.navbar}>
<li>
<NavLink
to='/login'
className={({
isActive,
}: {
isActive: boolean;
}): string | undefined =>
isActive ? styles.active : undefined
}
end
>
로그인
</NavLink>
</li>
<li>
<NavLink
to='/board'
className={({
isActive,
}: {
isActive: boolean;
}): string | undefined =>
isActive ? styles.active : undefined
}
>
글목록
</NavLink>
</li>
<li>
<NavLink
to='/write'
className={({
isActive,
}: {
isActive: boolean;
}): string | undefined =>
isActive ? styles.active : undefined
}
>
글쓰기
</NavLink>
</li>
</ul>
</nav>
</header>
</>
);
};
export default Header;
여기서 Link
와 NavLink
는 a태그와 역할이 같다.
className={({isActive,}: {isActive: boolean;}): string | undefined => isActive ? styles.active : undefined }
NavLink
는 자체적으로 isActive
라는 boolean 값을 가지고 있다.
위 코드는 링크가 활성화 되었을때, 링크에 active라는 클래스를 적용하는 코드이다. 모듈로 css를 불러올때는 string 값 이므로 type에 string을 넣어줬다.
타입 적용하는데 여기서 좀 애를 먹었었다.