- SPA가 무엇인지 설명할 수 있다.
- react-router-dom을 이용해 Router Component를 구현할 수 있다.
- react-router-dom을 이용해 Routing을 하는 방법 2가지와 차이점에 대해 설명할 수 있다.
<Link>
Component 와<a>
tag 의 차이점에 대해 설명할 수 있다.- css 전처리기의 역할에 대해 설명할 수 있다.
- sass에서 제공하는 문법을 이용하여 css파일을 scss파일로 변환할 수 있다.
SPA
(Single Page Application) 는 웹사이트에 페이지가 하나인 웹 애플리케이션.
여기서 ‘페이지’란 html 파일을 뜻하기 때문에, SPA는 html이 하나인 웹 애플리케이션을 의미한다.
상반되는 개념으로는 html 파일이 여러 개인 MPA
(Multi Page Application)가 있다.
애플리케이션이란 유저랑 상호작용할 수 있는 웹페이지를 이야기한다.
MPA는 html 파일이 여러 개라서 다른 페이지를 보여 주고 싶을 때, 해당 html 파일을 연결해 보여주는 형태로 페이지를 이동하는 기능을 구현할 수 있었다.
하지만 SPA는 html 파일이 하나이기 때문에 하나의 html에서 경로(url)에 따라서 다른 UI를 보여주는 라우팅 기능이 필요하게 된 것입니다.
CRA
를 통해서 만들 웹 애플리케이션은 SPA
이기 때문에 기존의 라우팅 방식과 다르게 라우팅을 구현해야한다.react-router-dom
은 React에서의 라우팅을 위해 가장 많이 사용되는 라이브러리
$ npm install react-router-dom
package.json
의 dependencies
항목에서 해당 패키지 명과 버전이 추가됐는지 확인
// 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"
}
}
💻 Router 컴포넌트를 만드는 이유
CRA를 통해 프로젝트를 만들고 npm start
를 터미널로 입력하면 최초 화면에서 App컴포넌트의 내용을 볼 수 있다. 하지만 아무리 url를 변경해도 똑같은 화면만 보이게 된다.
그래서 라우팅 기능을 구현하고 관리하기 위해서 Router 컴포넌트를 만들어 줘야한다.
💻 Router.js 파일 위치
Router.js 파일은 src
폴더 안 index.js
와 같은 위치에 생성하고, App.js
와 App.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;
BrowserRouter
- 주소 변경에 대해 다양한 편의 기능을 제공해 주는 컴포넌트.
대표적인 기능으로는 페이지가 새로고침 되지 않아도 주소 변경이 가능하게 하는 기능
Routes
- 여러 Route를 감싸서 그 중 규친이 일치라는 라우트 단 하나만을 렌더링 시켜주는 역할
Route
- 규칙을 설정할 수 있는 컴포넌트
path
와 element
속성을 사용하고 있는데 해당 속성의 뜻은
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
밖에 위치 시켜주면 된다.
이렇게 구현하면 어떤 경로는 항상 화면에 보여지게 된다.
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;
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;
react-router-dom
에서 useNavigate
를 import
useNavigate
함수를 실행하고, 해당 함수가 반환한 결과를 navigate
라는 변수에 할당.
여기서 useNavigate
가 반환하는 값은 페이지를 이동하는 함수이기 때문에, 결국 navigate
변수는 페이지를 이동하는 함수가 된다.
버튼을 눌러서 페이지를 이동하는 로직을 구현해야 하기 때문에 로그인 버튼에서 클릭 이벤트가 발생 시 호출할 함수를 만들어 준다.
button
태그에 onClick
이벤트를 생성하고 이벤트 발생 시 실행될 함수를 넣어줌.
React에서는 JSX의 특징 이용해서 이벤트를 걸어주고 싶은 태그에 속성을 설정하듯 직접 적용
🗒 Link 컴포넌트와 useNavigate hook의 차이점
- Link 컴포넌트는 연결에 제약이 없고 무조건 이동
- useNavigate hook 은 조건에 따라 제약을 걸어 페이지의 이동 여부를 따질 수 있다(선택)
예시) 로그인, 회원가입
<Link>
Component 와 <a>
tag 의 차이점에 대해 설명할 수 있다.Link컴포넌트의 구현된 화면 확인 시 a태그로 변환된 것을 볼 수 있다.
그렇다면 첨부터 a태그를 사용하면 될텐데 왜 Link컴포넌트를 사용하는 것일까?
<a>
tag외부페이지 이동 시 사용
a 태그를 직접 사용할 경우 페이지 이동 시 서버로부터 매번 새로운 페이지를 요청해서 받아옴.
그렇다면, 현재 화면에서 몇 가지만 바뀌어서 렌더링 되어야 하는 작업에서도 전체 화면을 매번 다시 렌더링하기 때문에 비효율적으로 동작.
외부 사이트로 이동할 때는 항상 전체 페이지를 새로 받아와야 하기 때문에 a
tag를 사용해야 함
<Link>
Component내부 페이지 이동 시 사용
Link 컴포넌트를 통해 변환된 a 태그는 실제 서버에 요청을 보내지 않고, 단지 url만 변경.
그래서 url의 변경을 react-router-dom
이 인지하고, 실제 화면에서 바뀌어야 하는 부분만 새로 렌더링되기 때문에 a 태그를 직접 사용하는 것보다 효율적
여러가지 기능들을 문법적으로 편히라게 작성할 수 있도록 제공하는 전처리기의 양식에 맞게 파일을 작성해두면, 그걸 최종적으로 실제 실행 전에 처리를 해줘서 브라우저가 읽을 수 있는 CSS 파일로 변환해 주는 일을 한다.
CSS 전처리기는 많은 종류가 있지만 그 중 Sass
를 가장 많이 사용한다.
전처리기(Preprocessor): 컴퓨터의 처리에 있어서 중심적인 처리를 수행하는 부분을 위해 사전 준비적인 계산을 행하는 프로그램
$ npm install sass
"sass": "^4.14.1",
확장자명 scss로 변경,import한 css파일의 확장가면도 scss로 변경
SPA 환경에서는 CSS파일이 겹칠 수 있기때문에 최상위 태그의 className을 컴포넌트 이름과 동일하게 부여
💻 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. 변수
// Sass 변수 활용 예시
$primary-color: #333;
body {
border: 1px solid black;
color: $primary-color;
}
.inverse {
background-color: $primary-color;
color: white;
}
💻 3. &
선택자
// Sass & 선택자 활용 예시
button {
width: 200px;
height: 50px;
&:hover {
width: 400px;
height: 100px;
}
}
💻 4. mixin
@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;
}
Sass
는 CSS 문법을 조금 더 편하게 작성할 수 있게 하고, scss 문법으로 작성한 파일을 실행 전에 처리를 해줘서 브라우저가 읽을 수 있는 CSS 파일로 변환해 주는 CSS 전처리기
.
기존 CSS 파일의 확장자를 scss로 변경하면 scss 문법이 사용 가능.
Sass
의 nesting
, mixin
등 다양한 기능을 활용해서 문법적으로 조금 더 편하게 스타일을 작성.
개발을 하며 새로운 기술을 학습하고 프로젝트에 적용하는 가장 확실한 방법은 공식문서를 보는 것.
공식 문서에 들어가 설치 방법부터 여러 가지 기능을 살펴보면서 효율적으로 활용.