Foundation1 - [React] Router & Sass

jini.choi·2023년 6월 12일
0

westudy

목록 보기
2/7

🚀 학습 목표

  • SPA가 무엇인지 설명할 수 있다.
  • react-router-dom을 이용해 Router Component를 구현할 수 있다.
  • react-router-dom을 이용해 Routing을 하는 방법 2가지와 차이점에 대해 설명할 수 있다.
  • <Link> Component 와 <a> tag 의 차이점에 대해 설명할 수 있다.
  • css 전처리기의 역할에 대해 설명할 수 있다.
  • sass에서 제공하는 문법을 이용하여 css파일을 scss파일로 변환할 수 있다.

SPA가 무엇인지 설명할 수 있다.

SPA (Single Page Application) 는 웹사이트에 페이지가 하나인 웹 애플리케이션.
여기서 ‘페이지’란 html 파일을 뜻하기 때문에, SPA는 html이 하나인 웹 애플리케이션을 의미한다.
상반되는 개념으로는 html 파일이 여러 개인 MPA (Multi Page Application)가 있다.

애플리케이션이란 유저랑 상호작용할 수 있는 웹페이지를 이야기한다.

MPA는 html 파일이 여러 개라서 다른 페이지를 보여 주고 싶을 때, 해당 html 파일을 연결해 보여주는 형태로 페이지를 이동하는 기능을 구현할 수 있었다.
하지만 SPA는 html 파일이 하나이기 때문에 하나의 html에서 경로(url)에 따라서 다른 UI를 보여주는 라우팅 기능이 필요하게 된 것입니다.


react-router-dom을 이용해 Router Component를 구현할 수 있다.

  • 리액트는 Library이기 때문에 라우팅 기늘이 내장되어있지 않다. 그래서 별도의 Livrary를 설치해서 라우팅을 구현해야하고, CRA를 통해서 만들 웹 애플리케이션은 SPA이기 때문에 기존의 라우팅 방식과 다르게 라우팅을 구현해야한다.

✅ 1. react-router-dom 설치

react-router-dom은 React에서의 라우팅을 위해 가장 많이 사용되는 라이브러리

$ npm install react-router-dom

package.jsondependencies 항목에서 해당 패키지 명과 버전이 추가됐는지 확인

// package.json

{
  "name": "react-project",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "react": "^18.0.0",
    "react-dom": "^18.0.0",
    "react-router-dom": "^6.3.0",
    "react-scripts": "3.4.3"
  }
}

✅ 2. Router 컴포넌트

💻 Router 컴포넌트를 만드는 이유
CRA를 통해 프로젝트를 만들고 npm start를 터미널로 입력하면 최초 화면에서 App컴포넌트의 내용을 볼 수 있다. 하지만 아무리 url를 변경해도 똑같은 화면만 보이게 된다.
그래서 라우팅 기능을 구현하고 관리하기 위해서 Router 컴포넌트를 만들어 줘야한다.

💻 Router.js 파일 위치
Router.js 파일은 src 폴더 안 index.js와 같은 위치에 생성하고, App.jsApp.css 파일은 제거.

💻 Router 컴포넌트 구현하기
Router 컴포넌트를 구현하기 위해선 BrowserRouter, Routes, Route 컴포넌트를 import 해야됨

// Router.js

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

const Router = () => {
  return (
    <BrowserRouter>                                  // 1                               
      <Routes>                                       // 2                            
        <Route path="/" element={<Components />} />  // 3
      </Routes>
    </BrowserRouter>
  );
};

export default Router;
  1. BrowserRouter 컴포넌트로 전체를 감싸줌
  2. BrowserRouter 자식요소로 Routes 컴포넌트 넣어줌
  3. Routes 컴포넌트의 자식 요소로 Route 컴포넌트 넣어줌
  • BrowserRouter
    - 주소 변경에 대해 다양한 편의 기능을 제공해 주는 컴포넌트.
    대표적인 기능으로는 페이지가 새로고침 되지 않아도 주소 변경이 가능하게 하는 기능

  • Routes
    - 여러 Route를 감싸서 그 중 규친이 일치라는 라우트 단 하나만을 렌더링 시켜주는 역할

  • Route
    - 규칙을 설정할 수 있는 컴포넌트
    pathelement 속성을 사용하고 있는데 해당 속성의 뜻은
    path 에 설정된 경로로 이동 시 element에 설정된 컴포넌트로 이동하라는 뜻

함수를 통해서 내부 페이지 이동할때 에러가 날 일이 없지만 유저가 없는페이지를 경로로 이동 시 경우의 수를 라우터에 걸어줘야됨(예외페이지)
<Route path="*" element={<Error />} />
*은 다른 페이지에 대해 속하지 않으면 404(error)페이지로 이동

💻 Router 컴포넌트 활용
경로에 상관없이 모든 화면에서 표시되어야 하는 컴포넌트는 어떻게 할 수 있을까?

// Router.js

import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Nav from './components/Nav/Nav';
import Footer from './components/Footer/Footer';
import Login from './pages/Login/Login';
import Signup from './pages/Signup/Signup';
import Main from './pages/Main/Main';

const Router = () => {
  return (
    <BrowserRouter>
      <Nav />                                          // nav 컴포넌트
      <Routes>
        <Route path="/" element={<Login />} />
        <Route path="/signup" element={<Signup />} />
        <Route path="/main" element={<Main />} />
      </Routes>
      <Footer />                                       // footer 컴포넌트
    </BrowserRouter>
  );
};

export default Router;

Router 컴포넌트는 여러 Route를 감싸서 그 중 규칙이 일치하는 라우틑 단 하나만 렌더링 시켜준다고 했다.
그렇다면 경로에 상관없이 보여주고 싶은 컴포넌트는 Routers 밖에 위치 시켜주면 된다.
이렇게 구현하면 어떤 경로는 항상 화면에 보여지게 된다.


react-router-dom을 이용해 Routing을 하는 방법 2가지와 차이점에 대해 설명할 수 있다.

  • Link 컴폰넌트를 import해서 JSX 내부의 원하는 곳에 사용할 수 있다.

  • to 라는 속성에 /signup이라는 경로가 적혀있는데,
    이를 통해 화면에서 회원가입이라는 글을 클릭하게 되면/signup 라는 경로로 이동하게 되고,
    Route 컴포넌트의 path값 중 일치하는 경로를 찾아 해당 컴포넌트를 화면에 그려준다.

// Login.js

import React from 'react';
import { Link } from 'react-router-dom';

const Login = () => {
  return <Link to="/signup">회원가입</Link>;
};

export default Login;

✅ useNavigate hook 사용하기

  • react-router-dom에는 Link 컴포넌트 외에도 라우팅을 구현할 수 있게 해주는 hook이 있다.
    여기서 hook은 함수 컴포넌트에서 다루지 못했던 기능들을 구현할 수 있게 도와주는 함수.

예시) 로그인 버튼 눌렀을 때 메인페이지로 이동

// Login.js

import React from 'react';
import { useNavigate } from 'react-router-dom';       // 1

const Login = () => {
  const navigate = useNavigate();                     // 2

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

  return (
    <button className="loginBtn" onClick={goToMain}>  // 4
      로그인
    </button>
  );
};

export default Login;
  1. react-router-dom에서 useNavigate를 import

  2. useNavigate 함수를 실행하고, 해당 함수가 반환한 결과를 navigate 라는 변수에 할당.
    여기서 useNavigate가 반환하는 값은 페이지를 이동하는 함수이기 때문에, 결국 navigate 변수는 페이지를 이동하는 함수가 된다.

  3. 버튼을 눌러서 페이지를 이동하는 로직을 구현해야 하기 때문에 로그인 버튼에서 클릭 이벤트가 발생 시 호출할 함수를 만들어 준다.

  4. button 태그에 onClick 이벤트를 생성하고 이벤트 발생 시 실행될 함수를 넣어줌.
    React에서는 JSX의 특징 이용해서 이벤트를 걸어주고 싶은 태그에 속성을 설정하듯 직접 적용

🗒 Link 컴포넌트와 useNavigate hook의 차이점

  • Link 컴포넌트는 연결에 제약이 없고 무조건 이동
  • useNavigate hook 은 조건에 따라 제약을 걸어 페이지의 이동 여부를 따질 수 있다(선택)
    예시) 로그인, 회원가입

Link컴포넌트의 구현된 화면 확인 시 a태그로 변환된 것을 볼 수 있다.
그렇다면 첨부터 a태그를 사용하면 될텐데 왜 Link컴포넌트를 사용하는 것일까?

<a> tag

  • 외부페이지 이동 시 사용

  • a 태그를 직접 사용할 경우 페이지 이동 시 서버로부터 매번 새로운 페이지를 요청해서 받아옴.
    그렇다면, 현재 화면에서 몇 가지만 바뀌어서 렌더링 되어야 하는 작업에서도 전체 화면을 매번 다시 렌더링하기 때문에 비효율적으로 동작.

  • 외부 사이트로 이동할 때는 항상 전체 페이지를 새로 받아와야 하기 때문에 a tag를 사용해야 함

  • 내부 페이지 이동 시 사용

  • Link 컴포넌트를 통해 변환된 a 태그는 실제 서버에 요청을 보내지 않고, 단지 url만 변경.
    그래서 url의 변경을 react-router-dom이 인지하고, 실제 화면에서 바뀌어야 하는 부분만 새로 렌더링되기 때문에 a 태그를 직접 사용하는 것보다 효율적


css 전처리기의 역할에 대해 설명할 수 있다.

  • 여러가지 기능들을 문법적으로 편히라게 작성할 수 있도록 제공하는 전처리기의 양식에 맞게 파일을 작성해두면, 그걸 최종적으로 실제 실행 전에 처리를 해줘서 브라우저가 읽을 수 있는 CSS 파일로 변환해 주는 일을 한다.

  • CSS 전처리기는 많은 종류가 있지만 그 중 Sass를 가장 많이 사용한다.

전처리기(Preprocessor): 컴퓨터의 처리에 있어서 중심적인 처리를 수행하는 부분을 위해 사전 준비적인 계산을 행하는 프로그램


sass에서 제공하는 문법을 이용하여 css파일을 scss파일로 변환할 수 있다.

  • Sass 설치
$ npm install sass
  • package.json의 dependencies 항목에서 해당 패키지 명과 버전이 잘 추가되었는지 반드시 확인
"sass": "^4.14.1",

✅ css파일을 scss파일로 변환

  1. 확장자명 scss로 변경,import한 css파일의 확장가면도 scss로 변경

  2. SPA 환경에서는 CSS파일이 겹칠 수 있기때문에 최상위 태그의 className을 컴포넌트 이름과 동일하게 부여

  • 각 컴포넌트에서 사용하는 className은 겹칠 수 있지만, 컴포넌트의 이름은 겹치면 안 되기 때문
  • 첫 번째 글자를 대문자로 적는 것은 컴포넌트 이름에 적용되는 네이밍 컨벤션이기 때문에, 최상위 부모 태그의 className은 카멜 케이스(camelCase)로 작성해야 함

✅ Sass의 활용

💻 1. Nesting

  • 마치 HTML 구조처럼 nav로 자식 관계에 있는 스타일을 품고, 그 안에 다른 태그들의 스타일을 적용하는 방법으로 구현할 수 있다.

  • Nesting구조로 관리하게되면 스타일을 변경을 주고 싶거나, 오류가 발생한 부분을 비교적 빠르게 찾아 수정할 수 있다.

  • 예시코드를 적용 후 구현된 화면을 보면 css로 변환된것을 확인할 수 있는데, 그 이유는 Sass가 CSS전처리기이기 때문에 컴퓨터가 읽을 수 있는 CSS파일로 자동으로 변환된다.

// src/pages/Login/Login.scss

nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li {
    display: inline-block;
  }

  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
  }
}

💻 2. 변수

  • css스타일을작성하다 보면 동일한 스타일 속성인데, 여러 곳에서 사용되거나 오타가 나기 쉬운 속성(rgb, hex)을 변수로 만들어 그 변수를 원하는 곳에 넣어서 사용하는 기능
// Sass 변수 활용 예시

$primary-color: #333;

body {
  border: 1px solid black;
  color: $primary-color;
}

.inverse {
  background-color: $primary-color;
  color: white;
}

💻 3. & 선택자

  • Nesting 내부에서 &선택자는 부모 선택자로 치환됨.
  • 예시로 button 태그에 스타일을 부여라고 해당 버튼에 hover 효과도 부여시 아래와 같이 구현
// Sass & 선택자 활용 예시

button {
  width: 200px;
  height: 50px;

  &:hover {
    width: 400px;
    height: 100px;
  }
}

💻 4. mixin

  • 중복되는 스타일 속성이 여러개가 있을 때 한번에 묶어서 사용하는 방법
  • @mixin 변수 이름 { 여러 가지 스타일 속성 } 과 같은 형식으로 구현
  • 스타일들이 사용되는 부분에 @include 변수 이름을 사용
  • mixin 공식문서: https://sass-lang.com/documentation/at-rules/mixin
// Sass mixin 활용 예시

@mixin flexCenter {
  display: flex;
  justify-content: center;
  align-items: center;
}

.info {
  @include flexCenter;
}

위와 같이 여러 스타일을 고정적으로 묶어서 사용하는 방법도 있지만 인자를 넣어서 스타일 속성의 틀은 유지한 채, 스타일 속성에 적용되는 값을 변경해서 적용할 수도 있다.

// Sass mixin 인수 활용 예시

@mixin flexSort($justify, $alignItems) {
  display: flex;
  justify-content: $justify;
  align-items: $alignItems;
}

.info {
  @include flexSort(space-between, center);
}

.feed {
  @include flexSort(space-around, center);
}

💻 5. variables.scss, mixin.scss 적용

  • 변수나 mixin을 다른 스타일 파일에서도 사용하고 싶다면 변수용 scss, mixin용 scss를 따로 만들어서 import 한다.

  • 짧으면 variables.scss, mixin.scss 를 합쳐서 variables.scss파일에 통일 하여도 됨

// src/styles/variables.scss

$primary-color: #333;
// src/styles/mixin.scss

@mixin flexCenter {
  display: flex;
  justify-content: center;
  align-items: center;
}

사용해야되는 스타일 파일에 임폴트하여 사용

// src/pages/Login/Login.scss

@import "../../styles/variables.scss";
@import "../../styles/mixin.scss";

body {
  border: 1px solid black;
  color: $primary-color;
}

.inverse {
  @include flexCenter;
  color: white;
}

✅ Summary

  • Sass는 CSS 문법을 조금 더 편하게 작성할 수 있게 하고, scss 문법으로 작성한 파일을 실행 전에 처리를 해줘서 브라우저가 읽을 수 있는 CSS 파일로 변환해 주는 CSS 전처리기.

  • 기존 CSS 파일의 확장자를 scss로 변경하면 scss 문법이 사용 가능.

  • Sassnesting, mixin 등 다양한 기능을 활용해서 문법적으로 조금 더 편하게 스타일을 작성.

  • 개발을 하며 새로운 기술을 학습하고 프로젝트에 적용하는 가장 확실한 방법은 공식문서를 보는 것.
    공식 문서에 들어가 설치 방법부터 여러 가지 기능을 살펴보면서 효율적으로 활용.

profile
개발짜🏃‍♀️

0개의 댓글

관련 채용 정보