같이 성장하는 프로그래밍

1-1 리액트 라우터 API 문서 (Hooks, useHistory) 본문

react router dom

1-1 리액트 라우터 API 문서 (Hooks, useHistory)

프설남 2020. 10. 11. 00:36
반응형

Hooks

 

React Router ships with a few hooks that let you access the state of the router and perform navigation from inside your components.

 

Please note: You need to be using React >= 16.8 in order to use any of these hooks!

 

  • useHistroy
  • useLocation
  • useParams
  • useRouteMatch

Hooks

 

리액트 라우터는 당신의 컴포넌트들 안에서부터 라우터의 state에 접근하거나 화면이동(navigation)을 수행하게 해주는 조금의 hooks를 가지고 있습니다.

 

노트 : 이 hooks들 중 어느것이든 사용하기 위해서는 리액트 16.8버전 이상을 사용할 필요가 있습니다.

 

  • useHistroy
  • useLocation
  • useParams
  • useRouteMatch

--설명을 보시려면 더 보기를 눌러주세요--

더보기

--라우터란?

라우터(router[a] 혹은 라우팅 기능을 갖는 공유기)는 패킷의 위치를 추출하여, 그 위치에 대한 최적의 경로를 지정하며, 이 경로를 따라 데이터 패킷을 다음 장치로 전향시키는 장치이다. -위키백과 출처-

 

=> 즉, 여기서는 화면과 화면을 연결시켜주고 이동을 시켜주는 장치라고 이해하시면 될 것 같습니다.

 

--라우터의 state란?

 

라우터의 state에는 기본적으로 history, location, match 라는 객체가 있습니다.

여기서 location 객체를 좀 자세히 보여드리겠습니다.

학교를 예시로 설명해보겠습니다. 3학년 1반(이하 3-1)이 있고 3-2, 3-3 있습니다.

3-1, 3-2, 3-3은 입구부터 차례대로 있습니다.

반 배정이 있는 날입니다. 저는 '/3-2#프설남' 이라는 종이를 받았습니다. 

입구와 제일 가까운 처음 3-1로 들어가려고 합니다. 막힙니다 ㅠ 왜냐고요? 저는 3-2 학생이니까요

그래서 다음 학급으로 들어갑니다. 종이에 3-2가 있으니 들어갈 수 있습니다.

여기서 '3-2 프설남'가 URL이 되고 '/3-2#프설남'에서 '/3-2'는 pathname이라는 '#프설남'은 hash라는 라우터의 state 중 하나인 location 객체의 state에 해당한다고 이해하시면 될 것 같습니다.

아래의 그림들을 봐 주세요.

 

 

(그림 1) URL

이 URL주소는 리액트라우터돔 공식홈페이지에 EXAMPLE에서 제가 설명하기 위해 만든 임의의 코드에 해당하는 URL주소입니다.

 

 

(그림 2) useLocation을 이용한 콘솔 결과

useLocation을 이용하여 (그림 1)에 해당하는 URL에 대한 location을 콘솔 창에 출력했고,
보시는 바와 같이 pathname, search, hash, state 들이 라우터의 state에 해당합니다.

 

 


1. useHistory

The useHistory hook gives you access to the history instance that you may use to navigate.

 

1. useHistory

useHistory hook은 화면이동에 사용할 수 있는 history 인스턴스에 접근하게 해준다.

 

--설명을 보시려면 더 보기를 눌러주세요--

더보기

--history 인스턴스

history 객체입니다.

리액트 라우터에서 화면이동을 할 때 항상 history, location, match 라는 객체에 필요한 정보들을 보내게 되어있습니다.

즉, 공식문서에서 말하는 history 인스턴스는 화면이동을 할 때 보내는 history, location, match 중 history에 해당합니다. 여기에 접근하게 해준다는 거죠.

아래의 그림에서 history 객체를 보실 수 있습니다.

 

 

(그림 3) useHistory를 이용한 콘솔 결과

보시면 history 객체는 location, createHref, push, replace, go, goBack, goForward, block, listen 라우터의 state를 가지고 있습니다.

공식문서의 '화면이동에 사용할 수 있는 history 인스턴스'를 보시면 '화면이동에 사용할 수 있는' 여기에 해당하는 것들이 push 부터 block 까지 화면이동하는 데 사용되는 함수들입니다.

 

예를 하나 들면 goBack() 함수를 사용하면 뒤로가기를 한 번하는 것과 같은 기능을 합니다.

 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { useHistory } from "react-router-dom";
 
function HomeButton() {
  let history = useHistory();
 
  function handleClick() {
    history.push("/home");
  }
 
  return (
    <button type="button" onClick={handleClick}>;
      Go home
    </button>;
  );
}
cs

(코드 1) useHistory 공식문서 예시 코드

 

 

 

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
  useHistory                 // hook 이라서 import React, {useHistory} from "react"; 가 아닙니다.
                             // 절~~대 제가 그래봤다는 건 아닙니다 :)
from "react-router-dom";
export default function BasicExample() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/">Index</Link> // html의 <a> 태그와 같은 기능
                                      // 누르면 to="/" 이니 URL이 '도메인/' 로 이동합니다.
          </li>
          <li>
            <Link to="/home">Home</Link> // 마찬가지로 to="/home" 이니 
                                         // 누르면 URL이 '도메인/home' 로 이동합니다.
          </li>
        </ul>
        <hr />
  
        <Switch>
          <Route exact path="/"> // URL을 확인하는 곳입니다.
                                 // path="/" 이니 URL이 '도메인/'로 시작하기만하면 전부 해당합니다.
                                 // 이렇게 되면 '도메인/abc'든 '도메인/efhuiwfheu'든 전부 통과합니다.
                                 // 그러나 exact가 있으므로 정확히 URL이 '도메인/'만 통과합니다.
                                 
            <Index />            // <Route exact path="/">의 검사를 통과하면 <Index /> 컴포넌트가 있으므로
                                 // <Index /> 컴포넌트를 렌더링(화면에 출력)합니다.
          </Route>
          
          <Route path="/home">   // path="/home" 이니 URL이 '도메인/home'으로 시작하기만 하면 전부 해당됩니다.
                                 // '도메인/home/bae'든 '도메인/home/fehuefhj'든 전부 해당되게 됩니다.
                                 // 즉, URL의 앞 '도메인/home'이 일치하므로 다 통과시킵니다.
                                 
            <Home />             // <Route path="/home">의 검사를 통과하면 <Home /> 컴포넌트가 있으므로
                                 // <Home /> 컴포넌트를 렌더링(화면에 출력)합니다.
                                 
          </Route>
        </Switch>
      </div>
    </Router>
  );
}
function Index() {            // Index 컴포넌트
  let history = useHistory(); // useHistory() hook을 사용하여 history 객체를 변수 history에 할당합니다.
  
  function handleClick(){     // 버튼을 클릭했을 때 실행시킬 handleClick 함수
    history.push('/home');    // history안에 있는 push 함수를 실행합니다.
                              // push(path, [state]) : path는 pathname에 해당 즉, URL주소
                              //                       [state] 는 [] 옵션이라는 뜻으로 생략해도 된다는 뜻입니다.
                              //                       반대로 path는 []로 안 감싸져있으니 필수로 넣어야한다는 뜻입니다.
                              //                       위 (그림 2)를 보시면 location 객체 속에 state:undefined 가 보일겁니다.
                              //                       거기에 넣을 정보를 넣을 때 이 옵션에 객체를 넣습니다.
                              // history.push('/home')는 즉, URL '도메인/home'으로 이동시켜줍니다.
                              // 새로고침이 되지 않습니다.(나중에 history.replace()와의 차이점이 됩니다.)
  }
  
  return (
    <div>
      <h2>Index</h2>
      <button type="button" onClick={handleClick}> // Go home 버튼
        Go home
      </button>
    </div>
  );
}
function Home() {               // Home 컴포넌트
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
cs

(코드 2) '코드 1'을 설명하기 위한 코드

 

 

 

(그림 4) '코드 2'의 Index 컴포넌트 화면

링크 Index와 Home이 리스트로 표시가 되고 

<hr/> 선이 그어지고

어느 <Route>를 통과한 컴포넌트가 출력됩니다.

여기선 <Route exact path="/"></Route>를 통과한 <Index />컴포넌트가 출력됩니다.

URL이 'https://bnpsd.csb.app/'에서 'https://도메인/'의 형식을 가집니다.

즉, 'bnpsd.csb.app'이 도메인입니다. 그리고 'bnpsd.csb.app'의 바로 뒤 '/' 부터 location 객체의 state인 pathname에 해당합니다.

 

여기서 Go home 버튼을 누르면 history.push('/home')이 실행될 것이고 결과는 어떻게 되겠습니까?

 

 

 

(그림 5) Go home 버튼을 누른 후 결과 화면

 

URL이 'https://bnpsd.csb.app/home' 로 바뀌었습니다!

즉 pathname이 '/' 였던 것이 history.push('/home')에 의해 pathname이 '/home'로 바뀌게 되었고,

URL의 주소가 바뀌었으니

리액트 라우터가 <Route>에서 다시 검사를 시작합니다.

 

자바스크립트는 기본적으로 위에서부터 차례대로 소스를 읽기 때문에

<Route exact path="/"> 부터 검사를 시작합니다.

자, 지금 pathname은 '/home' 입니다.

<Route exact path="/"> 에서 path='/'는 통과합니다. 왜냐 '/home'도 '/' 시작하기 때문입니다.

근데 exact가 있습니다? 정확히 path='/'가 아니므로 결국 통과하지 못합니다.

 

그럼 다음 <Route path="/home"> 으로 넘어가서 검사합니다. 

뭐 두말하면 잔소리입니다. 통과하게 되고 <Home /> 컴포넌트가 렌더링됩니다.

 


 

다음 글에서는 공식문서와는 순서를 다르게 history 객체의 state (location, createHref, push, replace 등)에 대해 설명하도록 하겠습니다.

 

 

긴 글과 글자 수가 많은데도 끝까지 읽어주셔서 정말 감사합니다!

 

부족한 부분이 있으면 언제든지 댓글 남겨주시면 감사하겠습니다!

반응형
Comments