React - 라우터

route에 대해서

Posted by Yan on February 2, 2021

리액트 라우터

먼저 라우터 라이브러리를 설치한다 yarn add react-router-dom

그리고 index.js에서 BrowserRouter컴포넌트를 추가한다

1
2
3
4
5
6
7
8
9
10
11
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { BrowserRouter } from "react-router-dom";

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

match

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

NewsPage.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import NewsList from "../components/NewsList";
import Categories from "../components/Categories";

const NewsPage = ({ match }) => {
  const category = match.params.category || "all";

  return (
    <>
      <Categories />
      <NewsList category={category} />
    </>
  );
};

export default NewsPage;

Route : 특정 주소에 컴포넌트 연결하기

path

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

1
2
3
4
5
6
7
8
9
10
11
import React from "react";
import { Route } from "react-router-dom";
import NewsPage from "./pages/NewsPage";
import "./style.css";

const App = () => {
  return <Route path="/:category?" component={NewsPage} />;
  //NewsPage컴포넌트로 이동. /:category?는 category 값이 필수가 아니라 옵션이라는 의미. 있을 수도 있고 없을 수도 있다.
};

export default App;

exact

<Route path="/" exact={true} component={Home} />와 같이 exact={true}가 들어가면

<Route path="/about" component={About} />와 같이 path의 일부분이 일치해도 정확하게 모든 path가 같은 것이 아니기때문에 About 컴포넌트는 화면에 나타나지 않는다 (exact사용 안하면 Home과 About이 같이 나타남)

Link 컴포넌트 : 클릭하면 다른 주소로 이동시키는 컴포넌트

  • a 태그의 기본 속성 : 페이지를 이동시키면서 페이지를 새로 불러옴. 리액트 앱이 지니고 있는 상태들도 초기화되고, 렌더링된 컴포넌트도 모두 사라지고 새로 렌더링됨.
  • 현재 활성화된 라우터의 스타일을 적용하기 위한 컴포넌트
  • Link의 확장된 기능
  • to에 지정된 path와 URL이 매칭되면 스타일이나 클래스를 적용할 수 있음

NewsPage.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import NewsList from "../components/NewsList";
import Categories from "../components/Categories";

const NewsPage = ({ match }) => {
  const category = match.params.category || "all";

  return (
    <>
      <Categories />
      <NewsList category={category} />
    </>
  );
};

export default NewsPage;

categories.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import styled from "styled-components";
import { NavLink } from "react-router-dom";

const Category = styled(NavLink)`
  font-size: 1.125rem;
  cursor: pointer;
  white-space: pre;
  text-decoration: none;
  color: inherit;
  padding-bottom: 0.25rem;

  &:hover {
    color: #495057;
  }

  &.active {
    font-weight: 600;
    border-bottom: 2px solid #22b8cf;
    color: #22b8cf;
    &:hover {
      color: #3bc9db;
    }
  }

  & + & {
    margin-left: 1rem;
  }
`;

const Categories = () => {
  return (
    <CategoriesBlock>
      {categories.map((c) => (
        <Category
          key={c.name}
          activeClassName="active" //activeClassName은 element가 active되었을 때 붙는 class이름이다. active가 기본값이다.
          exact={c.name === "all"} //카테고리 이름이 all일 때 exact=true라는 뜻
          to={c.name === "all" ? "/" : `/${c.name}`}
        >
          {c.text}
        </Category>
      ))}
    </CategoriesBlock>
  );
};

export default Categories;

NavLink로 만들어진 Category 컴포넌트

  • 카테고리 이름이 all일 경우 ‘/’만 설정 -> exact=true가 있어야 다른 카테고리와 중복이 생기지 않는다.
  • 카테고리 이름이 all이 아닐 경우 ‘/카테고리 이름’이 붙는다.