리액트를 다루는 기술 - 13장

velbie·2020년 10월 26일
1
post-thumbnail

SPA

예전에는 사용자에게 보이는 화면을 서버 측에서 준비했습니다. (요청할때마다 HTML 전송)
사용자와의 인터랙션이 자주 발생하는 모던 웹에서는 적당하지 않을수도 있습니다.
그래서 리액트 같은 라이브러리는 뷰 렌더링을 사용자의 브라우저가 담당하도록 합니다. (예전엔 아닌었나보네)
사용자와의 인터랙션이 발생하면 필요한 부분만 자바스크립트를 사용하여 업데이트 해줍니다.
SPA의 경우 서버에서 제공하는 페이지는 한 종류이지만, 해당 페이지에서 로딩된 자바스크립트와 현재 사용자 브라우저의 주소 상태에 따라 다양한 화면을 보여 줄 수 있습니다.
다른 주소에 다른 화면을 보여 주는 것을 라우팅이라고 합니다.

라우터 적용

react-router-dom에 내장되어 있는 BrowserRouter라는 컴포넌트를 사용하여 감싸면 됩니다. 이 컴포넌트는 웹 애플리케이션에 HTML5의 History API를 사용하여 페이지를 새로고침하지 않고도 주소를 변경하고, 현재 주소에 관련된 정보를 props로 쉽게 조회하거나 사용할 수 있도록 해 줍니다.

import { BrowserRouter } from "react-router-dom";

ReactDOM.render(
  <BrowserRouter>  // 이 부분
      <App />
  </BrowserRouter>,
  document.getElementById("root")
);

reportWebVitals();

home 와 about 컴포넌트를 만들고 라우팅해줬습니다.
/ 는 exact 라는 props를 true 설정해야 딱 그것만 나옵니다.

import React from "react";
import { Route } from "react-router-dom";
import About from "./About";
import Home from "./Home";

const App = () => {
  return (
    <div>
      <Route path="/" component={Home} exact={true} />
      <Route path="/about" component={About} />
    </div>
  );
};

export default App;

URL 파라미터

일반적으로 파라미터는 특정 아이디 혹은 이름을 사용하여 조회할 때 사용하고, 쿼리는 우리가 어떤 키워드를 검색하거나 페이지에 필요한 옵션을 전달할 때 사용합니다.

<Route path="/profile/:username" component={Profile} />

이런식으로 사용하면

import React from "react";

const data = {
  velopert: {
    name: "김민준",
    description: "리액트를 좋아하는 개발자",
  },
  gildong: {
    name: "홍길동",
    description: "고전 소설 홍길동전의 주인공",
  },
};

const Profile = ({ match }) => {
  console.log("match 가 들어오는지 확인", match);
  const { username } = match.params;
  const profile = data[username];
  if (!profile) {
    return <div>존재하지 않는 사용자압니다.</div>;
  }
  return (
    <div>
      <h3>
        {username}({profile.name})
      </h3>
      <p>{profile.description}</p>
    </div>
  );
};

export default Profile;

이런식으로 사용합니다. match 객체는 아래와 같은 구조를 가집니다.

{
  isExact: true
  params: {username: "velopert"}
  path: "/profile/:username"
  url: "/profile/velopert"
  }

URL 쿼리

yarn add qs 하고

import React from "react";
import qs from "qs";

const About = ({ location }) => {
  const query = qs.parse(location.search, {
    ignoreQueryPrefix: true,
  });
  const showDetail = query.detail === "true";
  return (
    <div>
      <h1>소개</h1>
      <p>
        .이 프로젝트는 리액트 라우터 기초를 실습해 보는 예제 프로젝트입니다.
      </p>
      {showDetail && <p> detail 값을 true로 설정하셧군요!</p>}
    </div>
  );
};

export default About;

통해서 쿼리스트링을 객체로 해서 값을 렌더했습니다.
브라우저에서 http://localhost:3000/about?detail=true 를 입력하면 됩니다.

서브라우트

그냥 라우트로 사용되고 있는 컴포넌트의 내부에 Route 컴포넌트를 또 사용하면 됩니다.
Profiles.js

import React from "react";
import { Link, Route } from "react-router-dom";
import Profile from "./Profile";

const Profiles = () => {
  return (
    <div>
      <h3>사용자 목록:</h3>
      <ul>
        <li>
          <Link to="/profiles/velopert">velopert</Link>
        </li>
        <li>
          <Link to="/profiles/gildong">gildong</Link>
        </li>
      </ul>

      <Route
        path="/profiles"
        exact
        render={() => <div>사용자를 선택해 주세요</div>}
      />
      <Route path="/profiles/:username" component={Profile} />
    </div>
  );
};

export default Profiles;

App.js

import React from "react";
import { Route, Link } from "react-router-dom";
import About from "./About";
import Home from "./Home";
import Profiles from "./Profiles";

const App = () => {
  return (
    <div>
      <ul>
        <li>
          <Link to="/"></Link>
        </li>
        <li>
          <Link to="/about">소개</Link>
        </li>
        <li>
          <Link to="/profiles"> 프로필</Link>
        </li>
      </ul>
      <Route path="/" component={Home} exact={true} />
      <Route path={["/about", "/info"]} component={About} />
      <Route path="/profiles" component={Profiles} />
    </div>
  );
};

export default App;

(감기몸살 걸림ㅜ)

리액트라우터 부가기능

history

history 객체는 라우트로 사용된 컴포넌트에 match, location 과 함께 전달되는 기본 props 중 하나 입니다.
특정 버튼을 눌렀을 때 뒤로 가거나, 로그인 후 화면을 전환하거나, 다른 페이지로 이탈하는 것을 방지해야 할 때 history를 활용합니다.

import React, { Component } from "react";

class HistorySample extends Component {
  // 뒤로 가기
  handleGoBack = () => {
    this.props.history.goBack();
  };

  handleGoHome = () => {
    this.props.history.push("/");
  };

  componentDidMount() {
    // 이것을 설정하고 나면 페이지에 변화가 생기려고 하 때마다 정말 나갈 것인지를 질문함
    this.unblock = this.props.history.block("정말 떠나실 건까요?");
  }

  componentWillUnmount() {
    // 컴포넌트가 언마운트 되면 질문을 멈춤
    if (this.unblock) {
      this.unblock();
    }
  }

  render() {
    return (
      <div>
        <button onClick={this.handleGoBack}>뒤로</button>
        <button onClick={this.handleGoHome}>홈으로</button>
      </div>
    );
  }
}

export default HistorySample;

withRouter

withRouter 함수는 라우트로 사용된 컴포넌트가 아니어도 match, location, history 객체에 접근하능합니다.

Switch

Switch를 사용하면 모든 규칙과 일치하지 않을 때 보여줄 Not Found 페이지도 구현할수 있습니다.

import React from "react";
import { NavLink, Route } from "react-router-dom";
import Profile from "./Profile";
import WithRouterSample from "./WithRouterSample";

const Profiles = () => {
 const activeStyle = {
   background: "black",
   color: "white",
 };
 return (
   <div>
     <h3>사용자 목록:</h3>
     <ul>
       <li>
         <NavLink activeStyle={activeStyle} to="/profiles/velopert" setAc>
           velopert
         </NavLink>
       </li>
       <li>
         <NavLink activeStyle={activeStyle} to="/profiles/gildong">
           gildong
         </NavLink>
       </li>
     </ul>

     <Route
       path="/profiles"
       exact
       render={() => <div>사용자를 선택해 주세요</div>}
     />
     <Route path="/profiles/:username" component={Profile} />
     <WithRouterSample />
   </div>
 );
};

export default Profiles;

링크말고 NavLink를 써야겠다.
링크가 활성화 되었을때 스타일을 적용할수 있습니다.

profile
안녕하세요

0개의 댓글