react-router-dom에서의 history는 session history를 관리하는 객체이다.( = history stack, navigate, session간에 동일하게 유지되는 state 등을 관리)
browser history
HTML5 history API를 지원하는 DOM 전용 구현체
hash history
legacy web browser를 위한 DOM 전용 구현체
memory history
React native와 같이 DOM을 지원하지 않는 환경과 testing을 위한 in-memory history 구현체
history 객체는 일반적으로 다음의 속성과 메서드들을 가지고 있다.
length
history stack에 쌓여 있는 entry의 개수
action
현재의 action(ex: push, replace, pop 등)
location : 현재 location
push(path, [state])
history stack에 새로운 entry를 올리는 함수
replace(path, [state])
history stack 최상단의 entry를 대체시키는 함수
go(n)
history stack의 포인터를 n번 앞으로(밑으로) 옮기는 함수
goBack() : go(-1)과 동일
goForward() : go(1)과 동일
block(prompt) : navigation 방지
import React, { useEffect } from "react";
import { useHistory, useLocation } from "react-router-dom";
const Comp = () => {
let history = useHistory()
const prevHistory = usePrevious(history);
let location = useLocation()
const prevLocation = usePrevious(location);
useEffect(() => {
const locationChanged = location !== prevLocation;
// 올바른 비교
const locationChanged = history.location !== prevHistory.location;
// history는 가변 객체이므로 항상 false를 반환하게 되니 잘못된 비교
})
// ...
}
function usePrevious(value) {
const ref = useRef();
useEffect(() => ref.current=value)
return ref.current;
}
// location 예시
{
key: 'ac3df4', // hashHitory에서는 제공되지 않는다
pathname: '/somewhere',
search: '?some=search-string',
hash: '#howdy',
state: {
[userDefined]: true
}
}
보통은 navigation path로 string을 전달하지만, 해당 path로 state를 전달하고자 할 때는 location 객체를 전달한다.
// usually all you need
<Link to="/somewhere"/>
// but you can use a location instead
const location = {
pathname: '/somewhere',
state: { fromDashboard: true }
}
<Link to={location}/>
<Redirect to={location}/>
history.push(location)
history.replace(location)
match 객체는 어떻게 Route path가 URL과 match되었는지에 대한 정보를 담는다.
params
URL을 파싱하여 얻은 key, value쌍으로 이루어진 객체
isExact
URL이 path와 '전체 일치'하는지에 대한 boolean값
path
match시키는데 사용된 path pattern
(Route컴포넌트를 중첩하는데 유용하다고 한다)
url
URL에서 path와 match되는 부분
(Link 컴포넌트를 중첩하는데 유용하다고 한다)
만약 Route컴포넌트가 path를 가지고 있지 않은 경우(...?) 항상 match될 수 밖에 없으므로, 가장 가까운 부모의 match를 얻게 된다. 이는 withRouter에서도 동일하다(무슨 소릴까)
https://reactrouter.com/web/api/match/null-matches
children prop을 사용하는 Route컴포넌트는 path가 현재 location과 일치하지 않더라도 children 함수를 호출할 것이다. 이 경우에 match의 값은 null이 된다.
(...?)