prefragrance / prefragrance-client

향으로 취향을 공유하고 나의 취향을 찾는 소셜미디어, 취향의 프론트엔드 저장소
0 stars 0 forks source link

App.js 구조 개편 건의 #9

Closed HiimKwak closed 2 years ago

HiimKwak commented 2 years ago

눈이 좀 괜찮아져서 코드를 찾아보다 흥미로운 구조를 발견해서 이슈에 올려봅니다

현재 저희 App.js의 구조를 살펴보면

import React from 'react';
import { Routes, Route } from 'react-router-dom';

import GlobalStyle from './GlobalStyle';
import Template from './Template';
import MainContainer from './components/shared/MainContainer';
import Home from './pages/Home';
import Detail from './pages/Detail';
import Nav from './components/shared/Nav';
import Search from './pages/Search';
import Footer from './components/shared/Footer';

const App = () => {
  return (
    <>
      <GlobalStyle />
      <Template>
        <Nav />
        <MainContainer>
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/detail" element={<Detail />} />
            <Route path="/search" element={<Search />} />
          </Routes>
        </MainContainer>
        <Footer />
      </Template>
    </>
  );
};

export default App;

App 컴포넌트 안에 구분 없이 Template 컴포넌트(width: 100%, margin: 0 auto;), Nav 컴포넌트, MainContainer 컴포넌트, Footer 컴포넌트가 나열돼있습니다

제 생각에 이 구조는 크게 문제는 없지만, 몇 가지 문제점이 있습니다

  1. 가독성이 떨어진다
  2. 그로 인해 컴포넌트 수정 시 구조를 헷갈리는 경우가 빈번하게 일어난다

한 눈에 전개해놓는 방식이 가독성이 매우 떨어지느냐라 묻는다면 무조건 그렇다고 대답할 순 없지만, 같은 기능과 목적을 가진 녀석들끼리 묶어 분리시켜놓는데 큰 힘이 들지 않는다면 굳이 안할 이유도 없습니다.

그리고 App 컴포넌트와 그 아래에 속한 컴포넌트의 내용을 수정하는 일이 꽤 자주 있었다는 것을 기억하신다면, 자주 들여다보는 코드일수록 보기 편하고 직관적이어야 추후에 바빠죽겠는데 제일 말단에 위치한 App 컴포넌트로 돌아와서 App.js 코드를 수정하고 있는 비효율을 없앨 수 있다라는 제 의견에 동의하실거라 생각합니다(살짝 비약같긴 하지만 또 생각해보면 틀린 말도 아님).

그래서 아래와 같이 개편할 것을 건의합니다

import "./App.css";
import Nav from "./components/Nav";
import Banner from "./components/Banner";
import Row from "./components/Row";
import requests from "./api/requests";
import Footer from "./components/Footer";
import MainPage from "./pages/MainPage";
import SearchPage from "./pages/SearchPage";
import { BrowserRouter, Routes, Route, Outlet } from "react-router-dom";
import DetailPage from "./pages/DetailPage";

const Layout = () => {
    return (
        <div>
            <Nav />
            <Outlet />

            <Footer />
        </div>
    );
};

function App() {
    return (
        <div className="app">
            <Routes>
                <Route path="/" element={<Layout />}>
                    <Route index element={<MainPage />} />
                    <Route path=":movieId" element={<DetailPage />} />
                    <Route path="search" element={<SearchPage />} />
                </Route>
            </Routes>
        </div>
    );
}

export default App;

핵심은 App.js에 Layout이라는 새로운 껍데기를 만들고 그것을 root router로 지정해주는 것입니다.

생각보다 별거 없지만 또 생각해보면 Layout이라는 구분을 새로 해주면, App 컴포넌트의 기능이 명확하게 Layout 관련 / Router 관련 두 가지로 나뉘게 됩니다.

그러면 저희 코드처럼 일렬로 산개돼있는 형태보다 훨씬 직관적이고, 추후에 Router를 추가하거나 Layout을 손봐야할 때 마치 형형 색색의 인덱싱이 돼있는 서류파일에서 손가락으로 이게 어디있지~ 하면서 읽어내려가지 않고 단번에 Layout 껍데기 혹은 Router 껍데기로 이동하여 작업할 수 있을 것입니다

비단 이 App 컴포넌트 뿐만 아니라, 저희가 짠 모든 컴포넌트에서 위와 같이 기능별로 구분짓는 작업을 해야할 필요성을 느껴서 위 코드를 가져오게 되었습니다.

읽어보시고 의견주십쇼. 감사합니다👍

HiimKwak commented 2 years ago

https://github.com/mju-likelion/dangme-frontend ㄴ readme가 가독성있게 정돈돼있어서 나중에 들여다볼 예정

zizonyoungjun commented 2 years ago

옹 좋은거같아요 ! 🥲

jellysoo97 commented 2 years ago

Layout이랑 Router 구분한 거 좋은 아이디어인 것 같습니다!

import React from 'react';
import { Routes, Route, Outlet } from 'react-router-dom';

import GlobalStyle from './GlobalStyle';
import Home from './pages/Home';
import Detail from './pages/Detail';
import Nav from './components/shared/Nav';
import Footer from './components/shared/Footer';

const Layout = () => {
  return (
    <div>
      <Nav />
      <Outlet />
      <Footer />
    </div>
  );
};

function App() {
  return (
    <>
      <GlobalStyle />
      <Routes>
        <Route path="/" element={<Layout />}>
          <Route index element={<Home />} />
          <Route path="/detail" element={<Detail />} />
        </Route>
      </Routes>
    </>
  );
}
export default App;
jellysoo97 commented 2 years ago

다만 이후에 위와 같은 레이아웃이 아닌 페이지가 나오면 (가령 Footer가 필요없다던가 Navbar가 없다던가) 어떻게 처리해야 할 지 논의해야 할 것 같습니다!

<Routes>를 새로 생성하면 되려나요?

HiimKwak commented 2 years ago

@jellysoo97 그러게요... layout 컴포넌트를 구분짓지 않아도 애초에 Navbar나 Footer가 필요없는 경우에 대한 유연한 대처가 안되는 문제가 있네요 실현 가능성이 있을지는 모르겠지만, Nav 컴포넌트나 Footer 컴포넌트 안에서 useParams로 파라미터를 가져와서 특정 파라미터일 경우에 컴포넌트 렌더링을 null값을 주는(삼항연산자 또는 if조건문으로) 방안을 생각해보긴 했습니다.

일단 그런 예외 케이스는 몇 개 안될 것 같기도 하고 지금 당장 해결해야 할 시급한 문제는 아니니 천천히 방안을 모색하면 좋을 것 같습니당

jellysoo97 commented 2 years ago
import React from 'react';
import { Routes, Route, Outlet } from 'react-router-dom';

import GlobalStyle from './GlobalStyle';
import Nav from './components/shared/Nav';
import Footer from './components/shared/Footer';

import HomePage from './pages/HomePage';
import DetailPage from './pages/DetailPage';
import SearchResultPage from './pages/SearchResultPage';

const Layout = () => {
  return (
    <div>
      <Nav />
      <Outlet />
      <Footer />
    </div>
  );
};

function App() {
  return (
    <>
      <GlobalStyle />
      <Routes>
        <Route path="/" element={<Layout />}>
          <Route index element={<HomePage />} />
          <Route path="/detail" element={<DetailPage />} />
          <Route path="/search" element={<SearchResultPage />} />
        </Route>
      </Routes>
    </>
  );
}

export default App;