티스토리 뷰

| Route

사용자가 요청하는 주소에 따라 다른 컴포넌트를 보여줘야할 때 Route 라는 컴포넌트를 사용합니다.

사용

<Route path="주소규칙" component={보여주고싶은 컴포넌트}>

위와 같은 방법으로 사용합니다.

하지만,

import logo from './logo.svg';
import './App.css';
import { Route } from 'react-router-dom';
import Home from './Home';
import About from './About';

function App() {
  return (
    <div>
      <Route path="/" component={About} />
      <Route path="/asd" component={Home} />
    </div>
  )
}
export default App;

위와 같은 코드를 작성하면
/ 경로에서는 About 컴포넌트를 잘 보여주지만, /asd 경로로 들어가면 About 컴포넌트와 함께 보여집니다.

이유는, /asd 경로가 / 규칙과도 일치하기 때문에 발생하는 현상입니다.

해결

About을 위한 라우트에 exact 라는 props 를 true 로 설정하면 됩니다 !
이 방법은 경로가 완전히 일치하는 경우에만 나타나게 해줍니다.

import logo from './logo.svg';
import './App.css';
import { Route } from 'react-router-dom';
import Home from './Home';
import About from './About';

function App() {
  return (
    <div>
      <Route path="/" exact={true} component={About} />
      <Route path="/asd" component={Home} />
    </div>
  )
}
export default App;

| Link

Link 컴포넌트는 클릭하면 다른 주소로 이동시키는 컴포넌트입니다.
리액트 라우터를 사용할 땐 <a href="~~~"> ~~~ </a> 태그를 사용하면 안됩니다.

만약에 구현하고 싶을 겨웅에는, onClick 속성에 e.preventDefault() 를 호출하고 따로 자바스크립트로 주소를 변환시켜주어야 합니다.

원인은, <a>태그 자체에는 기본 속성으로 페이지를 이동시키는 동시에 아예 새롭게 랜더링 시켜주기 때문입니다.
그렇게 되면서, 리액트들의 상태나 렌더링된 컴포넌트도 모두 사라지도 다시 렌더링하게 됩니다.

해결

따라서, Link 컴포넌트를 사용하면됩니다. 해당 컴포넌트는 HTML5 History API 를 사용하여 브라우저의 주소만 바꿀뿐 페이지를 새로 불러오지 않습니다.

사용법

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

function App() {
  return (
    <div>
      <ul>
        <li>
          <Link to="/" >홈</Link>
        </li>
        <li>
          <Link to="/about">소개페이지</Link>
        </li>
      </ul>

      <hr />
      <Route exact={true} path="/" component={Home} />
      <Route path="/about" component={About} />
    </div>
  )
}
export default App;

| 파라미터와 쿼리

페이지 주소를 정의할 때, 유동적이게 전달해야합니다.
예를들어

파라미터 : /example/param1
쿼리 : /example?search=true

일반적으로, 특정 id 나 이름을 갖고 조회를 할 때 사용하며
쿼리의 경우에는 어떤 키워드를 검색하거나 요청을 할 때 필요한 옵션을 전달 할 때 사용됩니다.
path 규칙에는 :사용할변수명 으로 넣어주면 변수명에 알맞는 값을 파라미터로 넣어주어 Profile 컴포넌트에서 match props를 통해 전달받을 수 있습니다.

파라미터 받기

파라미터를 받을 땐 match 안에 들어있는 params 값을 참조합니다
match 객체 안에는 현재의 주소가 Route 컴포넌트에서 정한 규칙과 어떻게 일치하는지에 대한 정보가 들어있습니다.

import React from 'react';

// 프로필에서 사용 할 데이터
const profileData = {
  haha: {
    name: 'asd',
    description:
      'sdddd'
  },
};

const Profile = ({ match }) => {
  // 파라미터를 받아올 땐 match 안에 들어있는 params 값을 참조합니다.
  const { username } = match.params;
  const profile = profileData[username];
  if (!profile) {
    return <div>존재하지 않는 유저입니다.</div>;
  }
  return (
    <div>
      <h3>
        {username}({profile.name})
      </h3>
      <p>{profile.description}</p>
    </div>
  );
};

export default Profile;

경로를 /profiles/haha 에 들어가면 data들이 출력이됩니다.

쿼리 받기

쿼리는 라우트 컴포넌트에게 props 전달되는 location 객체에 있는 search 값에서 읽어올 수 있습니다.
location 객체는 현재 앱이 갖고 있는 주소에 대한 정보를 지니고 있습니다.

location 객체 샘플

{
  key: 'ac3df4', // not with HashHistory!
  pathname: '/somewhere'
  search: '?some=search-string',
  hash: '#howdy',
  state: {
    [userDefined]: true
  }
}

위의 객체의 값에서 search 를 확인야 하는데, 이 값은 문자열 형태로 되어있습니다.
따라서 객체 형태로 변환 해야합니다.

해당 작업은 qs라이브러리를 사용하여 쉽게 할 수 있습니다.

$ yarn add qs
import React from 'react';
import qs from 'qs';

const About = ({ location }) => {

  //location.search 의 문자열값을 qs라이브러리로 parse해줍니다.
  const query = qs.parse(location.search, {
    ignoreQueryPrefix: true
  });

  const detail = query.detail === 'true'; // 쿼리의 파싱결과값은 문자열입니다.

  return (
    <div>
      <h1>소개</h1>
      <p>이 프로젝트는 리액트 라우터 기초를 실습해보는 예제 프로젝트랍니다.</p>
      {detail && <p>추가적인 정보가 어쩌고 저쩌고..</p>}
    </div>
  );
};

export default About;

그 이후 /about?detail=true 경로에 들어가보면 추가 정보가 잘 나옵니다.

| 서브라우트

서브 라우트는, 라우트 내부의 라우트를 만드는것입니다.

'React' 카테고리의 다른 글

리덕스 모듈 만들기  (0) 2021.02.16
리덕스(Redux) 와 리덕스의 구성요소  (0) 2021.02.16
styled-components  (0) 2021.02.13
class형 component  (0) 2021.02.11
Immer 를 이용한 불변성 관리  (0) 2021.02.11