[ React ] Route props__history object

양찌·2021년 6월 9일
0

React

목록 보기
2/4

이 포스팅은 아래의 자료를 참고하였습니다.



history

컴포넌트 안에 있는 브라우저 히스토리를 핸들링 할 수 있도록 해줍니다. 쉽게 말하면, url이 바뀔 때의 그 url들의 기록을 stack에 담아서 관리하도록 해주는 것이라고 할 수 있습니다.
리액트 history를 이용하여 뒤로 가기, 앞으로 가기를 할 수 있습니다. 데이터를 가지고 오거나, side-effect 이후에 URL을 바뀔 수 있습니다.

  • length - (number) 히스토리 스택에 담긴 숫자
  • action - (string) 최신 액션(PUSH, REPLACE, or POP)
  • location - (object) 최신 로케이션
    - pathname - (string) URL의 path
    - search - (string) URL 쿼리 스트링
    - hash - (string) URL 해쉬 프래그먼트
    - state - (object) 로케이션이 스텍에 push될 때, e.g.push(path, state)에게 제공된 구체적인 로케이션 상태.
    브라우저와 메모리 히스토리에서만 사용가능.
  • push(path, [state]) - (function) 히스토리 스텍에 new entry를 push한다.
  • replace(path, [state]) - (function) 히스토리 스텍에 최신 entry를 replace한다.
  • go(n) - (function) n entry 만큼 히스토리 스텍에 있는 포인터를 옮긴다.
  • goBack() - (function) go(-1)과 같음
  • goForward() - (function) go(1)과 같음
  • block(prompt) - (function) 현재 페이지로부터 이동을 막는다.


The history is mutable.
객체 히스토리는 변한다.

따라서 reatrouter 공식 문서에서는 history.location이 아닌, location 객체(<Route>에서 렌더링 되는 props 중 한 속성인 location)를 사용해서 접근하는 것을 추천합니다. 라이프사이클에서 구현 내용을 확신하기 위해서입니다.


코드 구현

앞서 설명했던 Route props 중 하나인 match object ( Route props__match object )의 코드를 이용해 보겠습니다.

import { BrowserRouter as Router, Link, Switch, Route } from 'react-router-dom';

function App() {
  return (
    <div className="App">
      <Router>
        <h1>Router match</h1>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/mypage">MyPage</Link>
            </li>
            <li>
              <Link to="/topics">Topics</Link>
            </li>
          </ul>
        </nav>

        <Switch>
            <Route exact path="/" component={Home} />
            <Route path="/mypage" component={MyPage} />
            <Route exact path="/topics" component={Topics} />
            <Route path="/topics/:topicId" component={TopicDetail} />
        </Switch>
      </Router>
    </div>
  );
}

function Home() {
  return <h1>Here is Home.</h1>
}

function MyPage() {
  return <h1>Here is MyPage.</h1>
}

function Topics({match}) {
  return <TopicList match={match}/>
}

function TopicList({match}) {
  console.log({match})
  return (
    <div>
      <h3>Topics List View</h3>
      <ul>
          <li>
            <Link to={`${match.url}/topic1`}>Topic 1</Link>
          </li>
          <li>
            <Link to={`${match.url}/topic2`}>Topic 2</Link>
          </li>
          <li>
             <Link to={`${match.url}/topic3`}>Topic 3</Link>
          </li>
      </ul>
    </div>
  )
}

function TopicDetail({match}) {
  return(
    <div>
      <h3>{match.params.topicId}</h3>
      <Link to="/topics">Go back to "/topics"</Link>
    </div>
  )
}

export default App;



history.push 사용하기

최종 구현 화면

history.push를 사용하여 버튼 topic1이 mypage로 이동하도록 해보겠습니다.

코드 구현

앞 코드에서 주석처리 된 부분을 수정하고, 변수 fireHistory를 추가해 보겠습니다.
<Route component={Topics}>에서 <Topics> 로 전달 받은 props 중 history 객체의 push 속성을 이용하였습니다. URL을 바꿔 해당 페이지로 이동하는 것을 확인 할 수 있습니다.
(<Route> props의 원리를 이해하기 위해서 Route props__match object를 참고하시기 바랍니다.)

function TopicList({match, history}) {
// console.log('history',history)

  const fireHistory = () => {
    return history.push(`/mypage`)
  }
  
  return (
    <div>
      <h3>Topics List View</h3>
      <ul>
          <li>
            <button onClick={fireHistory}
            >topic1</button>
          </li>
          //<li>
          	//<Link to={`${match.url}/topic1`}>Topic 1</Link>
          //</li>
          <li>
            <Link to={`${match.url}/topic2`}>Topic 2</Link>
          </li>
          <li>
             <Link to={`${match.url}/topic3`}>Topic 3</Link>
          </li>
      </ul>
    </div>
  )
}



만약 topic1을 URL /topic/topic1로 이동하기 위해서는 코드를 어떻게 작성하면 좋을까요?


const fireHistory = () => {
  return history.push(`${match.url}/topic1`)
}

클릭할 때 사용하는 이벤트 함수 fireHistory에서 푸쉬하는 URL만 변경해주면 됩니다.


history.go 시리즈 사용하기

history.goBack()과 history.goForward()를 사용하여 앞으로 가기, 뒤로 가기 기능을 만들어 보겠습니다.
추가로 history.push()를 이용하여 홈으로 가는 기능을 추가해 보겠습니다.

최종 구현 화면

코드 구현

history 객체를 사용할 수 있도록 새로운 컴포넌트를 만들어 보겠습니다.

function HistoryGo({history}) {
  const goHome = () => {
    return history.push('/')
  };
  
  const goBack = () => {
    return history.goBack()
  };
  
  const goForward = () => {
    return history.goForward()
  }
  
  return (
    <div>
      <button onClick={goHome}>홈으로</button>
      <button onClick={goForward}>앞으로 가기</button>
      <button onClick={goBack}>뒤로가기</button>
    </div>
  )
}

버튼이 눌렸을 때 각각의 이벤트 핸들러 함수(goHome, goForward, goBack)를 실행시킵니다.



이때 주의 할 점은 <HistoryGo> 컴포넌트는 부모로부터 history라는 props를 받고 있습니다. 부모 컴포넌트에서<HistoryGo>컴포넌트를 import 해오고 그 안에 넣어 줘야 합니다.

  • 예시)
import { Link } from "react-router-dom";
import HistoryGo from "../Components/HistoryGo";

function TopicDetail({ match, history }) {
  return (
    <div>
      <h3>{match.params.topicId}</h3>
      <Link to="/topics">go back to "/topics"</Link>
      <HistoryGo history={history} />
    </div>
  );
}



최종 코드 확인

Route props__history object

profile
신입 개발자 입니다! 혹시 제 글에서 수정이 필요하거나, 개선될 부분이 있으면 자유롭게 댓글 달아주세요😊

0개의 댓글