이 포스팅은 아래의 자료를 참고하였습니다.
컴포넌트 안에 있는 브라우저 히스토리를 핸들링 할 수 있도록 해줍니다. 쉽게 말하면, url이 바뀔 때의 그 url들의 기록을 stack에 담아서 관리하도록 해주는 것이라고 할 수 있습니다.
리액트 history를 이용하여 뒤로 가기, 앞으로 가기를 할 수 있습니다. 데이터를 가지고 오거나, side-effect 이후에 URL을 바뀔 수 있습니다.
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를 사용하여 버튼 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.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>
);
}