TIL 22-04-22

thisisyjin·2022년 4월 22일
0

TIL 📝

목록 보기
29/113

React.js

Today I Learned ... react.js

🙋‍♂️ React.js Lecture

🙋‍ My Dev Blog


React Lecture CH 9

1 - React Router
2 - Link, BrowserRouter
3 - Hash Router, params, withRouter
4 - location, match, history
5 - 쿼리스트링, URLSearchParams
6 - render props, switch, exact

SPA 프레임워크인 React에서는 페이지가 하나지만, 실제로는 여러개인 눈속임을 위해 React-Router가 필요하다.

  • 우선, 터미널에서 npm install(또는 yarn add)로
    react-routerreaact-router-dom을 설치한다.
npm i react-router react-router-dom
  • react-router는 그저 뼈대이고, react-router-dom이 있어야 웹에서 동작할 수 있다.
    (만약 앱에서 사용하려면? react-router-native를 설치)

  • 우리가 사용하는 것은 react-router-dom이고,
    react-router은 react-router-dom가 내부적으로 필요로 하는 것.


BrowserRouter

지금껏 만들었던 게임들을 한 페이지로 구현해보자.

Games.jsx

import React from 'react';
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
import BullsAndCows from './BullsAndCows';
import RSP from './RSP';
import Lotto from './Lotto';

const Games = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/number-baseball" element={<BullsAndCows />} />
        <Route path="/rock-scissors-paper" element={<RSP />} />
        <Route path="/lotto-generator" element={<Lotto />} />
      </Routes>
    </BrowserRouter>
  );
};

export default Games;

Routes > Route

  • 우선, BrowserRouter로 전체를 감싸준다.
    (BrowserRouter 아니면 HashRouter을 주로 사용한다.)
  • Route path='' component={}의 형태로 작성해주는데,
    Route들은 Routes로 감싸져야한다.
  • path에는 가상의 주소를 적어준다.
  • 지금은 도메인이 없으므로, localhost:8080/number-baseball과 같은 주소가 된다.
  • 페이지가 여러개 있는 것이 아닌, 여러개 있는 척을 하는 것.
    (페이지가 실제로 존재하지 않고, 가상으로 만들어낸 페이지임)

이제, a태그로 해당 주소로 이동하도록 만들어보자.
단, 보통의 a href="" 로 작성하면 에러가 발생한다.

-> react-router-dom의 Link를 사용한다.

<Link to="/sub-page" element={<Sub />}>Text</Link>

-> Dev Tool의 Element 탭을 보면, 이는 a태그로 나와있다.


Result

  • Routes 바깥에 있는 부분은 (Link들) 바뀌지 않는다.
  • 분명 하나의 페이지지만, 마치 여러 페이지가 있는 것 처럼 동작함.
    -> 이때, 주소는 바뀌게 됨. (가상의 주소임)

/number-baseball과 같은 path는 실제로 존재하는 것이 아니므로, 주소창에 직접 입력하거나 새로고침시 `Cannot GET /number-baseball 이라는 에러가 발생함.
-> 주소창에 직접 입력하거나 새로고침 하는 것은, 서버측에 요청을 보내는 것임.
-> Link를 통해서만 이동 가능.(=프론트엔드에서만 동작함)


HashRouter

위 Games.jsx 코드에서 BrowserRouter을 HashRouter로 바꿔본다.

import React from 'react';
import { HashRouter, Routes, Route, Link } from 'react-router-dom';
import BullsAndCows from './BullsAndCows';
import RSP from './RSP';
import Lotto from './Lotto';

const Games = () => {
  return (
    <HashRouter>
      <Link to="/number-baseball">숫자야구</Link>
      &nbsp;
      <Link to="rock-scissors-paper">가위바위보</Link>
      &nbsp;
      <Link to="/lotto-generator">로또생성기</Link>
      <Routes>
        <Route path="/number-baseball" element={<BullsAndCows />} />
        <Route path="/rock-scissors-paper" element={<RSP />} />
        <Route path="/lotto-generator" element={<Lotto />} />
      </Routes>
    </HashRouter>
  );
};

export default Games;

http://localhost:8080/#/number-baseball
이런식으로 path 앞에 해시(#)가 붙게 된다.

동작상 큰 차이는 없지만, 새로고침을 해도 화면이 정상적으로 보인다.
(BrowserRouter에서는 새로고침시 서버에 요청을 하게 되고, 실제 페이지가 아니므로 에러가 발생했었다.)

HashRouter에서는 새로고침시에도 에러없이 동작한다.
URL에서 해시(#) 뒤 부분은 브라우저만 알고 있는 부분.
-> 서버는 해시(#) 뒤 부분을 인식하지 못함.
따라서, 에러가 발생하지 않고 정상 작동.

❗️ 서버에선 인식하지 못하므로, SEO(search engine optimizing)에 적합하지 않다.
-> 해시라우터는 실무에서 잘 사용하지 않음.
(** BrowserRouter도 SEO를 위해서는 추가작업 필요하긴 함)

서버 세팅

  • SEO를 위해서는 서버쪽 설정이 필요하다.
  • BrowserRouter에서 새로고침을 하면 에러가 발생하는데,
    이를 해결하기 위해 각 path를 등록해줘야한다.

동적 라우팅

  • <Route>들이 계속해서 많아지게 된다면?
  • 동적 라우트 매칭이 필요하다.
  • GameMatcher 컴포넌트를 생성한다.

GameMatcher.jsx

import React, { Component } from 'react';

export default class GameMatcher extends Component {
  render() {
    return <div>게임 매쳐</div>;
  }
}
  • Params를 이용한 동적 Route를 추가한다.

Games.jsx

<Route path="/game/:name" element={<GameMatcher />} />
  • :name은 실제로 name이 아닌 params라고 한다. (=파라미터)
  • params는 number-baseball이 될수도 있고, lotto-generator이 될수도 있다. (=동적으로 바뀜)
<Link to="/game/index">게임 매쳐</Link>

params를 임의로 index라고 정하여 Link를 추가해준다.

  • 게임매쳐 Link(=a태그) 클릭시, GameMatcher 컴포넌트의 내용이 렌더링된다.
<Link to="/game/number-baseball">숫자야구</Link>
<Link to="/game/rock-scissors-paper">가위바위보</Link>
<Link to="/game/lotto-generator">로또생성기</Link>
  • 기존 Link에도 앞에 /game/을 붙여준다.
    number-baseball, rock-scissors-paper, lotto-generator는 모두 name이라는 params가 된다.
<Routes>
   <Route path="/game/:name" element={<GameMatcher />} />
 </Routes>
  • 총 세개였던 Route를 하나로 줄일 수 있다!

GameMatcher.jsx

import React, { Component } from 'react';

export default class GameMatcher extends Component {
  render() {
    console.log(this.props);
    return <div>게임 매쳐</div>;
  }
}
  • GameMatcher 컴포넌트 내부에서 this.props에 저장되어 있다.

  • 컴포넌트 분기.

render() {
  if (this.props.match.params.name === 'number-baseball') {
    return <NumberBaseball />
  } else if (this.props.match.params.name === 'rock-scissors-paper') {
    return <RSP />
  } else {
    return <Lotto />
  }
}
* * *

강의 내용이 React Router 6 이전 버전인 것 같아서
이후 내용들은 따로 기록하지 않고, 공식 문서 로 대체하도록 함.

profile
기억은 한계가 있지만, 기록은 한계가 없다.

0개의 댓글