리액트 파일구조 (+ router 사용법)

hyerin·2023년 4월 29일
0

리액트는 컴포넌트형 라이브러리이기 때문에, 이들을 잘 분리하고 조합해야 하며, 그러기 위해서는 필수적으로 파일구조가 중요하다.
가장 큰 파일구조는 다음과 같다.

1. components

: 전역적으로 공유하는 components를 넣는 파일. 한 페이지에서만 공유되는 components는 pages에 따로 만들어준다. 이 파일은 전체적으로 공유해야하는 components들을 위해 사용한다. 수업시간엔 Layout이라는 파일을 만들어 그 안에 header, footer를 넣었다. layout은 공용 컴포넌트라고 하기에는 좀 애매해서 밖에다 폴더로 빼기도 한다.

그리고 페이지에서 공통적으로 들어가는 Button을 만들어 넣어놀 수도 있다.

2. pages

각 페이지를 포함하는 pages폴더이다. 각 페이지는 또 다른 폴더의 형태로 저장된다. 예를 들면 메인 페이지의 경우 main으로 저장된다. 페이지폴더 안에는 파일명을 지을때 기본적으로 index.js라고 짓는데, 이는 그 페이지의 가장 기본 파일이라는 뜻이다. 물론 다르게 지어도 문제는 없다. index.js로 지으면 import할때 상위 파일이름만 쳐도 index.js파일이 연결되기 때문에, 가독성이 좋아진다는 장점이 있다. 이 파일외에도 해당 페이지에 필요한 하위 컴포넌트를 포함한 components파일, 페이지의 공통 css를 모아놓은 css파일 등이 포함되기도 한다.

위 사진의 경우 pages는 main페이지와 todo페이지로 구성되어 있고, main페이지의 경우 SignIn과 Signup으로 이루어져 있다. 이 두 컴포넌트를 연결하는 index.js 파일이라는 기본 파일도 있다. style.css의 경우는 pages에서만 공통되는 css를 모아놓은 파일이다. style.css은 참고로 다음과 같이 만들 수 있다.

//pages> style.css
//공용으로 style을 쓰기 위해서 공용화하기
import styled from "styled-components";
import { flexCenter } from "../../styles/global";
export const Form = styled.form`
  width: 360px;
  background-color: #ffffff;
  ${flexCenter}
  flex-direction: column;
  padding-top: 32px;
`;

export const InputBox = styled.div`
  width: 80%;
  height: 48px;
  ${flexCenter}
  margin-bottom: 16px;
`;

이 css 파일에서는 styled component를 사용해서 공통되는 컴포넌트를 만들어 주었다. 이 css는 페이지의 컴포넌트에서 import 해서 사용할 수 있는데, 이 예제에서는 다음과 같이 import 해서 사용하였다.

//pages> Components > SignIn.js
import * as S from "../style";
//S라는 별칭으로 모든 것을 가져온다.
const SignInForm = () => {
  return (
    <>
      <S.Form>
        <S.InputBox>
          <label>이메일</label>
          <input />
        </S.InputBox>
        <S.InputBox>
          <label>비밀번호</label>
          <input />
        </S.InputBox>
        <button>로그인</button>
      </S.Form>
    </>
  );
};
export default SignInForm;

3. routes

routes 파일의 경우 route를 관리하는 역할을 하는 파일이다. 기본적으로 route의 방식으로는 2가지가 있다.

  1. RouteProvider, createBrowserRouter를 사용하는 방법
  2. BrowserRouter, Routers, Router를 사용하는 방법

1. RouteProvider, createBrowserRouter를 사용하는 방법

이 방법을 요약하자면 다음과 같다

(1) App.js파일에서 다음과 같이 <RouterProvider>태그를 생성한다. 이 또한 router-dom에서 import후 사용해야 한다.

//Aoo,js
import {RouterProvider} from "react-router-dom"
import router from "./routes/routing"

function App() {
 <RouterProvider router={router} />
}
export defualt App;

RouterProvider태그를 보면 하위컴포넌트에 router로 router를 전달한것을 알 수 있다.이는 import 해온 routing 파일의 router로 이렇게 전달하면 routing.js에서 지정한 router를 쓸 수 있다. routing.js에서 지정한 routing.js파일은 다음과 같다.

//src > routes> routing.js
import { createBrowserRouter } from "react-router-dom";
import TodoPage from "../pages/todo";
import MainPage from "../pages/main";
import Layout from "../components/Layout";
import React from "react";

const router = createBrowserRouter([
  {
    element: <Layout />,
    children: [
      {
        path: "/",
        element: <MainPage />,
      },
      { path: "/todo/:todoId", element: <TodoPage /> },
    ],
  },
]);

위 routing 파일은 크게 createBrowserRouter에 인자로 배열이 담겨져 있고, 그 배열안에 객체형태의 route가 담겨져 있는것을 볼 수 있다. 각 객체는 element, path라는 크게 두가지 속성으로 이루어져 있다. children에 포함된 객체는 하위 라우터로 상위 라우터를 물고 있는 형태이다.이런 형태로 라우터를 지정하면 라우터들이 배열형태로 되어 있으므로 배열 메소드인 map등을 사용할 수 있으며, 직관적이라는 장점이 있다.
참고로 각 페이지 컴포넌트는 당연히 import 해야 한다.

상위 라우터 객체로 Layout이라는 컴포넌트가 있는 것을 볼 수 있다. 이 컴포넌트는 하위 라우터페이지가 모두 포함하는 컴포넌트로 component폴더에 Layout이라는 파일로 지정되어 있다.

다음과 같이 작성되어 있다. 여기서 특이한 점은 <Outlet/>라는 태그가 import 되어 포함되어 있다는 점이다. 이는 Layout안에 어디에서 children 라우터 페이지가 나올지를 표시하는 태그이며 필수적이다. 이 경우에는 <Header/><Footer/> 컴포넌트 사이에 라우터 주소에 따라 <MainPage/><TodoPage/>가 포함된다.

import { Outlet } from "react-router-dom";
const Layout = () => {
  return (
    <>
      <Header />
      <Outlet />
      {/* 감싸고 있는 경로중에 맞는 경로를 가져와준다. */}
      <Footer />
    </>
  );
};

2. BrowserRouter, Routers, Router를 사용하는 방법

다음은 App.js에서 구현한 예제이다.

import { RouterProvider, BrowserRouter, Routes, Route } from "react-router-dom";

function App() {
  return (
    <div>
      {/*html5를 지원하는 브라우저의 url변화를 감지함*/}
      <BrowserRouter> 
      {/*하위에 있는 route 컴포넌트 중 url과 path가 일치하는 컴포넌트만 보여주는 역할
        주소변화를 감지해서 path와 일치하는 element만 보여줘!*/}
      <Routes>
      {/*path를 안적으면 모두 적어준다
          밑 구 라우터중에서 맞는것에 outlet을 담아준다.
          */}
     	 <Route element={Layout}>
           	 <Route path="/" element={<MainPage />} />
             <Route path="/todo" element={<TodoPage />} />
          </Route>
       </Routes> 
      </BrowserRouter>
    </div>
  );
}

export default App;

크게 다음과 같은 형식으로 이루어져 있다.

<BrowserRouter> > <Routes> > <Route>

우선 가 브라우저의 url을 감지하고, 에 포함된 에 따라 해당 path와 url이 일치하면 해당 element로 지정한 컴포넌트가 나오는 형식이다. 는 여러개 지정할 수 있으며, 그 하위의 또한 개수는 자유롭다.

이 방식을 쓸 때도 <Layout/>컴포넌트에 <Outlet/>을 지정해야 하는 것은 동일하다.

4. styles

common : 공용
global : 전역
theme : 테마
keyframes : 애니메이션

이 4개의 파일이 보통 들어가는데 프로젝트에서 공용으로 쓰는 공통적인 css속성이 들어간다.

요약: 보통 이렇게 크게 4가지 종류의 파일이 src에 들어간다. 물론 이는 고정된 것이 아니며, 회사의 컨벤션에 따라 언제든지 바뀔 수 있다.

5. hooks

훅 폴더는 내가 커스텀한 훅함수를 넣어두는 폴더이다. 이를 커스텀 훅이라고 하는데, 보통 일반 훅함수 처럼 앞에 use를 붙이는 것이 컨벤션이다. 훅함수를 사용해서 자주 사용할 것 같은 컴포넌트를 만들어 넣는다.

profile
글쓰기의 시작은 나를 위해, 끝은 읽는 당신을 위해

0개의 댓글