[React] Outlet을 활용한 header, footer 놓기(feat react-router-dom v6.4)

개잼·2024년 6월 27일
0
post-custom-banner

1. 인사

안녕하세요. 이번에는 react-router-dom을 이용하는 과정에서 header와 footer를 놓는 방법을 소개하려고 합니다.


2. 소개배경

과거 프로젝트를 rebuilding하던 와중 react-router-dom을 lastest download 했는데 좀 새롭게 바뀌었더군요. 요즘 Nextjs 위주로 프로젝트 하다가 react-router-dom을 이용한 route를 하려니 약간 불편하였습니다. 신박하기도 했구요. 그래서 글로 정리해보려고 합니다.


3. 기존 Source code

  • index.js
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <Provider store={store}>
      <BrowserRouter>
        <RecoilRoot>
        <App />
        </RecoilRoot>
      </BrowserRouter>
    </Provider>
);
  • App.js
return (
    <div className="App">
      <Header/>
      <Routes>
           <>
               <Route path="/" element={<Home />}/>
               <Route path="/detail/:id" element={<Detail/>}></Route>      
           </>
      </Routes>
    </div>
);

이런식으로 작성하면 Header는 고정된 상태로 "/"이나 "/detail/:id" 진입했었습니다. 그런데 이것은 예전 방식이 되어버린 것이죠.


4. 그래서 어케하는데?

길게 끌거 없이 바로 본론으로 넘어가봅시다.

  • index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { Route, RouterProvider, createBrowserRouter, createRoutesFromElements } from 'react-router-dom';
import Login from './pages/Login';
import NavBar from './components/NavBar';
import Home from './components/Home';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);

const router = createBrowserRouter(
  createRoutesFromElements(
    <Route path="/" element={<App />}>
      <Route path="/" element={<Home />}/>
      <Route path="/login" element={<Login />}/>
    </Route>
  )
)


root.render(
  <React.StrictMode>
    <RouterProvider router={router}/>
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

먼저 index.tsx를 다음과 같이 작성합니다.
참고 : 공식문서


여기서 중요한 것은

<Route path="/" element={<App />}>

와 같이 parent route elements가

<Route path="/" element={<Home />}/>
<Route path="/login" element={<Login />}/>

child route elements를 가져야 한다는 것입니다.
이것이 중요한 이유는 Outlet을 통해 Header와 Footer는 child route가 rendering될 때 중첩될 수 있도록 만들기 때문입니다.

  • App.tsx
import { Outlet } from "react-router-dom";
import NavBar from "./NavBar";
import Footer from "./Footer";

export default function App() {
    return (
        <div className="flex flex-col h-screen">
            <NavBar />
            <Outlet />
            <Footer />
        </div>
    );
}

여기서 중요한 것은 Outlet입니다.
아까 위에서 제가 언급했듯이 parent route elements와 child route elements개념에 따라 App.tsx인 parent route elements가 "/"에서 rendering되고 그 이후에 child route elements인 home이나 Login이 각각 "/", "/login"에서 rendering될 때 Outlet 자리에 Home이나 Login component가 들어가게 되어 NavBar와 Footer가 항상 중첩되어 보일 수 있게 되는 것입니다.
참고 : 공식문서



5. 정리

지속적인 libray update에 따라 다시 해당 library를 공부해야 함이 다소 번거롭다고 생각은 들지만, 학습을 했을 때 즐거움이 있기에 힘들어도 앞으로 나아갈 수 있는 것 같습니다.
이 글을 보시고 피드백이 필요한 부분이나 더 간단한 방법을 아시는 분들은 댓글 남겨주시기 바랍니다. 감사합니다.

profile
천천히 나아가는 중
post-custom-banner

0개의 댓글