본문 바로가기
Front-End/React

[React] 플랫폼 메인구조(헤더, 사이드바, 푸터) 특정 페이지에만 적용하기

by SeanK 2023. 3. 2.

안녕하세요, 프론트엔드 개발자 Sean입니다. 

 

오늘은 플랫폼에서 메인구조(헤더, 사이드바, 푸터)를 특정 페이지에만 적용하려면 어떻게 해야 하는지에 대해 정리한 내용을 올려볼까 합니다. 

 

사실 오늘 플랫폼 리펙토링 중에 페이지를 바꿀 때 마다 상단 헤더의 이미지 아이콘이 깜빡 거리는 사실을 알게 되었습니다. 원인은 페이지를 바꿀 때 메인구조가 리렌더링 되었기 때문이었습니다. 이러한 이유가 발행한 이유는 라우팅 되는 컴포넌트 안에 메인구조 컴포넌트를 삽입하는 형태였기 때문에 페이지를 변경하면 매번 같은 메인구조를 다시 그렸던 겁니다. 

 

예를 들어 라우터는 path='/에 Dashboard.js 컴포넌트를 불러오고 해당 컴포넌트 안에 MainStructure.js 컴포넌트가 들어있는 구조였습니다. 

 

이 문제를 해결하려면 MainStructure.js를 상위 컴포넌트로 끌고 와 메인스트럭처 내에 페이지 컴포넌트가 바뀌도록 제어를 해주어야 합니다. 문제는 대부분의 페이지가 메인구조를 가지지만 로그인/회원가입 등 일부 페이지에서는 메인구조를 가지지 않는다는 점입니다. 이런 경우 React-router-dom에서 문제를 어떻게 해결해야 할까요?

 

방법은 아래와 같습니다. 

 

우선 라우팅을 하는 코드를 아래와 같이 구조화 할 수 있습니다. 

<BrowserRouter>
    <Routes>
        <Route path="/" element={<MainStructure />} >
          <Route path="/" exact={true} element={<Dashboard />} />
          <Route path="dashboard" element={<Dashboard />} />
          <Route path="/mylist/settings" exact={true} element={<Settings />} />
          <Route path="/mylist/followings" exact={true} element={<Followings />} />
          <Route path="/company/:id" exact={true} element={<CompanyDetails />} />
          <Route path="/search" exact={true} element={<Search />} />
          <Route path="/analytics/:id?" element={<Analytics />} />
        </Route>
        <Route path="callback/kakao" exact={true} element={<KakaoRedirect />} />
        <Route path="callback/google" exact={true} element={<GoogleRedirect />} />
        <Route path="privacy" exact={true} element={<Privacy />} />
        <Route path="verify" exact={true} element={<Verify />} />
        <Route path="terms" exact={true} element={<Terms />} />
        <Route path="signup" exact={true} element={<Signup />} />
        <Route path="signin" exact={true} element={<Signin />} />
        <Route path='*' element={<Signin />} />
    </Routes>
  </BrowserRouter>

위에 보시면 <Route> 태그안에 또 다른 <Route> 태그가 들어있습니다. 이렇게 라우팅을 nest 하면 일부페이지에서는 메인구조가 나오고 일부페이지에서는 나오지 않도록 할 수 있습니다.

 

하지만 이대로 실행해 보시면 아마 페이지 라우팅이 제대로 동작하지 않을 겁니다. 

 

마지막으로 하나 더 작업해줄게 남았습니다. 바로 Outlet을 적용하는 것입니다. 

Outlet은 자식 엘리먼트를 렌더링 하도록 상위 엘리먼트에 붙여주어야 합니다. 

 

그래서 저는 아래와 같이 붙여주었습니다.

import { Outlet } from 'react-router-dom';

class MainStructure extends Component {
  render() {
    const { children, main } = this.props;

    return (
      <>
        <Header />
        <section>
          <div className="main-section">
            <div className='nav'>
              <Sidebar/>
            </div>
            <main className={'main ' + main}>{children}</main>
            <Outlet />
          </div>
        </section>
      </>
    );
  }
}

이러면 깜빡이는 불편한 동작없이 스무스하게 SPA의 장점을 최대한 이용할 수 있는 페이지 라우팅이 가능하게 됩니다.