TIL. React - Basic 개념 정리(7)

ichbinmin2·2021년 2월 7일
0

React

목록 보기
18/25
post-thumbnail

👩🏻‍💻 면접 기출 문제를 준비하면서, React를 이해할 때 반드시 필요한 기본 개념들들 추가로 정리해보았다.

▪️ Routing in Web 이란?

http requests를 어떤 특정한 페이지로 연결 할 것인지를 결정하는 메커니즘을 말한다. 즉, 사용자가 url을 줬을 때 어떤 페이지로 연결할 건지를 결정하는 역할을 한다.


SPA(Single Page Application)
React는 SPA를 쉽게 만들 수 있는 라이브러리이다. 하나의 url로 페이지가 최초 한 번 로딩되고 나면 그 안에서 사용자가 다른 페이지를 클릭하거나 링크를 클릭했을 때 (새로운 페이지가 열리거나 전체적으로 리프레쉬 되는 것이 아니라), 해당하는 component- 부분적인 component 내용만 비교해서 업데이트 해주는 것이 바로 SPA 이다. 해당하는 component만 바꿔줌으로써 사용자가 페이지에서 나가지 않고 같은 자리에서 원하는 데이터를 동적으로 받아와서 동적으로 볼 수 있게 해준다.

문제점
SPA의 방식으로는 (뒤로가기-앞으로가기 같은) 네비게이션이 추가가 되지 않는다. SPA의 특성상 하나의 페이지 안에서만 동작이 가능하기 때문이다. 이러한 이슈를 보완하기 위해서 등장한 것이 Router 이다. Router 란 SPA를 유지하면서도 url을 붙여 네이게이션을 추가할 수 있도록 해주는 라이브러리이다.


▪️ Routing이란 무엇인가?

Routing은 네트워크에 있는 traffic의 path를 선택하는 프로세스를 의미한다. 일반적으로 네트워크에서 Routing이란 네트워크 상에서 우리가 특정 url을 이용했을 때, 어떤 경로를 통해서 데이터를 받아 올 것인지를 결정해주는 역할을 한다.

yarn add react-router-dom
// router 설치 명령어
  • 예제
import "./App.css";
import { BrowserRouter, Switch } from "react-router-dom";
import Home from "./components/home";
import Profile from "./components/profile";

function App() {
  return (
    <BrowserRouter>
      <Switch>
        <Route path="/home">
          <Home />
        </Route>
        <Route path="/profile">
          <Profile />
        </Route>
      </Switch>
    </BrowserRouter>
  );
}

export default App;

📌 BrowserRouter : BrowserRouter는 Router를 최상위의 부모로 감싸줘야 하기 때문에 쓰인다.

📌 Switch : 해당하는 경로에 맞게 우리가 어떤 Component를 보여줄 것인지 결정할 때 사용하는 Component 이다.

tip. 만약 다른 이름으로 사용하고 싶다면 import 할 때 as 를 이용하여 수정해주고 그대로 사용하면 된다.

import { BrowserRouter as 원하는이름 } from "react-router-dom";
  • ** Router로 경로 설정을 마친 component 예시 **

home.jsx

import React from "react";

const Home = (props) => {
  return (
    <>
      <h1>home</h1>
      <button
      >
        Go To Profile
      </button>
    </>
  );
};

export default Home;

profile.jsx

import React from "react";

const Profile = (props) => {
  return (
    <>
      <h1>Profile</h1>
      <button
      >
        Go To Home
      </button>
    </>
  );
};

export default Profile;

실행 결과

각각의 Component는 Router로 설정해놓은 경로 path="/경로" 에 맞춰서 해당하는 경로 페이지로 이동할 수 있게 되었다.

이처럼 app.js 라는 index가 실행이 되고, index에서는 어플리케이션이 실행이 되며 어플리케이션 안에서는 BrowserRouter 라는 최상위 컴포넌트가 자동적으로 실행이 되고 있다.

💬 최상위 경로로 home 을 두고 싶다면 어떻게 해야 할까?

Route 에서 경로를 설정하고 싶을 때 사용하는 것이 바로 path 이다.

function App() {
  return (
    <BrowserRouter>
      <Switch>
        **<Route path={["/", "/home"]}>**
          <Home />
        </Route>
        <Route **path="/profile"**>
          <Profile />
        </Route>
      </Switch>
    </BrowserRouter>
  );
}

export default App;

실행 결과

경로가 "/home" 이거나, "/" 일때도 둘다 path 경로로 설정한 Home Component 페이지가 열리는 것을 확인할 수 있다.

📌 <Link> : <Switch> 밖에서 사용하면 간단하게 해당하는 경로로 이동할 수 있도록 해준다.

function App() {
  return (
    <BrowserRouter>
      <nav>
        **<Link to="/">Home</Link>**
        **<Link to="/profile">Profile</Link>**
      </nav>
      <Switch>
        <Route path={["/", "/home"]} exact>
          <Home />
        </Route>
        <Route path="/profile">
          <Profile />
        </Route>
      </Switch>
    </BrowserRouter>
  );
}

export default App;

✔️ 하지만 클릭을 했음에도 불구하고 각각의 경로로 이동하지 않는다. 이때 필요한 솔루션이 바로 exact 이다.

이미지를 확인해보자. boolean type의 exact를 사용하면 one 이라는 path를 결정한 뒤에 이 one 다음에 다른 경로가 들어있지 못하도록 Matche를 no로 설정이 된다. 해당 경로에 true로 설정하지 않으면 false로 지정되고 이 경로 안에 one 이라는 경로가 포함되어 있기 때문에 yes가 되며, one 다음에 다른 경로가 왔을 때 one이라는 경로로 다시 돌아오게 된다. 이러한 문제를 해결하기 위해서는 이 route에 exact라는 boolean의 속성값을 전달해줘야 한다. 즉, 해당 경로에 exact라는 속성값을 전달해주면 true(다른 경로가 오지 못하도록)가 된다.

해당 Home component 속성 값으로 exact를 전달해보자.

function App() {
  return (
    <BrowserRouter>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/profile">Profile</Link>
      </nav>
      <Switch>
        <Route path={["/", "/home"]} exact>
          <Home />
        </Route>
        <Route path="/profile">
          <Profile />
        </Route>
      </Switch>
    </BrowserRouter>
  );
}

export default App;

실행 결과

해당 <Link> 를 클릭하면 각각 경로 path로 설정해준 Component 페이지로 정상적으로 이동되는 것을 확인할 수 있다. exact를 속성값으로 준 <Home> Route에서는 path에서 설정한 경로(path={["/", "/home"]}) 다음에 들어오는 모든 경로들이 Route에 들어오지 않는다. 즉, 다시 (path={"/"}) 으로 돌아오지 않고, 각각 설정한 해당 경로로 정상적으로 이동하게 된다.

💬 각각의 component에서 버튼을 눌렀을 때 다른 component로 넘어가고 싶다면 어떤 방법을 써야할까?

1. component를 사용해서 props로 넘겨주던 과거의 이동 방식

import Home from "./components/home";

<Route path={["/", "/home"]} exact component={Home} />

comoponent를 props로 (전달)이용하면 Router는 react.createElement 를 이용한다. 그래서 component를 전달하면 이것을 이용해서 새로운 react component를 만든다. 그 말인 즉슨, 매번 render 될 때마다 새로운 component를 만드는 것과 동일하다. 이미 mount 된 component가 unmounting이 되고, 새로운 component가 mount 된다. 이러한 문제 때문에 성능에 대한 이슈가 있으며, 최근에는 이러한 방식을 더이상 추천하지 않는다.

공식문서 에서도 확인할 수 있듯이, 과거에는 component를 사용해서 props로 넘겨주던 Router 이동 방식을 주로 사용했으나, 최근에는 props으로 넘겨주면서 history를 이용하여 네비게이션과 같은 경로 이동을 가능하게 하는 방법으로 변화하였다.

2. React Hooks의 useHistory 함수를 이용한 이동 방식

react-router-dom 에서 useHistory 를 import 해준 후에 새로이 변수 선언을 한 history를 .push 로 이용하여 이동하고 싶은 경로를 설정해주었다.

import React from "react";
import { useHistory } from "react-router-dom";

const Home = (props) => {
  const history = useHistory();
  return (
    <>
      <h1>home</h1>
      <button
        onClick={() => {
          history.push("/profile");
        }}
      >
        Go To Profile
      </button>
    </>
  );
};

export default Home;
import React from "react";
import { useHistory } from "react-router-dom";

const Profile = (props) => {
  const history = useHistory();
  return (
    <>
      <h1>Profile</h1>
      <button
        onClick={() => {
          history.push("/");
        }}
      >
        Go To Home
      </button>
    </>
  );
};

export default Profile;

실행 결과

버튼을 클릭하면 각각 해당하는 component 경로로 이동되는 것을 확인할 수 있다. routing을 이용했기 때문에 뒤로가기 앞으로 가기 등의 네비게이션 기능도 사용할 수 있다.

이처럼 과거엔 component를 props로 넘겨서 경로를 이동하던 시기가 있었으나 최근에는 앞서 사용한 방식으로 Router를 사용하길 권장하고 있다. 공식문서

✔️ 정리

html에서 링크를 사용하여 페이지를 이동하던 과거에는 전체적인 html 페이지가 다른 html 페이지로 교체되는 등의 비효율적인 방법으로 이동을 할 수 밖에 없었다. 그러나, 최근에 등장한 React Routing 은 기존의 페이지는 그대로 유지한 상태에서 즉, SPA(싱글 페이지 어플리케이션)에서 제공하는 장점을 그대로 사용하면서도 네이게이션 기능 또한 이용할 수 있게 되었다. 또한 과거에는 Routing을 구현할 때 component를 props로 넘겨서 경로를 이동하는 방식으로 매번 새로운 component를 render 하게되면서 다소 성능에 대한 이슈가 있었으나, 최근의 React Hooks의 등장으로 useHistory라는 자체적인 함수를 사용하여 이러한 이슈 또한 해결할 수 있게 되었다.


**출처 **
React Router: Declarative Routing for React
React Router: path-string-stringt
React Router: exact
React Router: Hooks

profile
조화로움을 꿈꾸는 개발자, Teta Min

0개의 댓글