[westagram] React : Router, Sass

nomadhj·2022년 5월 10일
0

[westagram] React

목록 보기
2/5

React를 이용한 westgram 리팩토링 - Router와 Sass 적용 기록

1. Router

  • 라우팅이란 경로에 따라 다른 화면을 보여 주는 것
    이를 활용하면 SPA(Single Page Application)를 구성 할 수 있다.

  • 기존에 javascript로 작성한 westagram 코드로 리액트 프로젝트를 생성한 후 라우팅을 적용하였다.

  • 처음에는 단순하게 하나의 html 페이지에서 경로에 따라 Login 페이지와 Main 페이지를 렌더링 할 수 있도록 <Router> 컴포넌트를 아래와 같이 구현하였다.

import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Login from "./pages/Login/Login";
import Main from "./pages/Main/Main";

const Router = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Login />} />
        <Route path="/main" element={<Main />} />
      </Routes>
    </BrowserRouter>
  );
};

export default Router;
  • 위와 같이 구현한 <Router>컴포넌트를 아래와 같이 index.js의 render() 함수에 추가하면 간단하게 경로에 따라 페이지를 렌더링 하도록 라우팅을 구현할 수 있다.
import React from 'react';
import ReactDOM from 'react-dom/client';
import Router from './Router';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <Router />
);
  • 라우팅을 구현 후 로그인 페이지에서 버튼을 눌렀을 때 다른 라우트(메인 페이지)로 이동하기 위해서 사용할 수 있는 방법으로는 <Link> 컴포넌트를 이용하는 방법과, useNavigate훅을 이용하는 두 가지 방법이 있다.
  • 먼저 <Link> 컴포넌트를 이용하는 방법을 살펴보면 다음과 같다.
    • 아래 코드에서 <button> 태그 내부를 보면 <Link> 컴포넌트를 적용하고 to라는 props를 활용하여 경로를 '/main'으로 지정해주었다.
    • <Link> 컴포넌트는 DOM에서 <a>태그로 변환되지만 <a>태그와 달리 다른 라우트로 이동 시 새로고침을 하지 않고 변화되는 UI만 새로 렌더링 하기에 더 효과적으로 동작한다.
    • 따라서 외부 링크로 이동하는 경우가 아니면 아래와 같이 <Link> 컴포넌트를 사용해야 한다.
import "./Login.scss";
import { Link } from "react-router-dom";

function Login() {
  return (
    <div className="login">
      <section className="loginSection">
        <p className="logo">Westagram</p>
        <input
          className="username"
          type="text"
          placeholder="전화번호, 사용자 이름 또는 이메일"
        />
        <input className="password" type="password" placeholder="비밀번호" />
        <button className="loginBtn" disabled={false}>
          <Link to="/main">로그인</Link>
        </button>
      </section>
    </div>
  );
}

export default Login;
  • 두 번째 방법으로 useNavigate 훅을 사용한 코드는 아래와 같다.
    • button 태그에 onClick 이벤트를 설정하여 버튼 클릭이 발생했을 goToMain 함수가 실행되도록 하였다.
    • goToMain 함수는 navigate("/main")을 실행하는데, 여기서 navigate는 useNavigate 훅이 리턴한 함수를 할당한 변수로, Link 컴포넌트의 to props와 동일한 방식으로 작동한다고 볼 수 있다.
    • 그러나 useNavigate 훅을 사용할 경우 Link 컴포넌트를 사용할 때에 비해 여러 장점이 있는데, 이 경우만 보더라도 이벤트 발생 시 호출되는 함수에 구현됨에 따라 Link 컴포넌트 단독으로 사용할 때에 비해 여러 추가 로직들을 넣을 수 있다는 장점을 확인 할 수 있다.
import "./Login.scss";
import { useNavigate } from "react-router-dom";

function Login() {
  const navigate = useNavigate();

  const goToMain = () => {
    navigate("/main");
  };

  return (
    <div className="login">
      <section className="loginSection">
        <p className="logo">Westagram</p>
        <input
          className="username"
          type="text"
          placeholder="전화번호, 사용자 이름 또는 이메일"
        />
        <input className="password" type="password" placeholder="비밀번호" />
        <button className="loginBtn" disabled={false} onClick={goToMain}>
          로그인
        </button>
      </section>
    </div>
  );
}

export default Login;

2. Sass 적용

  • Sass를 적용함에 있어 자세한 적용 방법보다 주의할 내용이 있어 해당 내용을 기록하였다.

  • Sass의 주요 기능으로는 Nesting 기능이 있어, Css 문서를 마치 HTML 태그를 처럼 구성 할 수 있다.

  • 하지만 해당 Nesting 기능을 적용함에 있어 아래와 같은 사항을 주의할 필요가 있다.

    1. Nesting의 지나친 적용은 코드 깊이가 깊어져 가독성을 해칠 필요가 있으니, 필요한 경우에만 사용한다.
    2. Nesting을 적용하다 보면 의도치 않게 CSS 우선순위가 바뀔 수 있으니 주의한다.
  • 특히 위의 2번 사항 때문에 이 항목을 작성하였다.
    기존에 westgram Main 페이지 적용 시 화면 폭에 따른 미디어 쿼리를 아래와 같이 적용했었다.

@media screen and (max-width: 1200px) {
    section.mainRight {
        display: none;
    }
    section.feeds {
        width: 60%;
    }
}
  • Nesting을 적용하는 과정에서 section.mainRight과 section.feeds CSS 속성을 아래와 같이 적용했었다.
.main {
	...
  .westgram {
  	...
	main {
    	...
    	section.mainRight { ... }
        section.feeds {...}
    }
  }
}
  • 이는 마치 .main > .westgram > main > ... 와 같은 식으로 작성 된 것이나 마찬가지라 우선 순위가 바뀌어 미디어 쿼리가 적용되지 않는 문제가 발생하였다.
  • 이를 해결하기 위해서는 미디어 쿼리 역시 아래와 같이 작성해야 했다.
@media screen and (max-width: 1200px) {
  .main { 
    .westagram{
      main{
        section.mainRight {
          display: none;
        }
        section.feeds {
          width: 60%;
        }
      }
    }
  }
}
  • 따라서 가독성 측면 뿐만 아니라 이러한 문제를 고려해보았을 때 Nesting의 무분별한 적용은 주의해야 한다.
profile
프론트엔드 개발과 맥주에 관심 있습니다.

0개의 댓글