React-router v5.1, 무엇이 달라졌을까?

React로 개발할 때 라우팅을 하기 위해 주로 사용되는 react-router가 9월 25일 v5.1로 업데이트되었습니다.

v5.1에서는 올해 2월 react v16.8에 추가된 hooks API가 추가되었는데요, 같이 어떤 기능들이 새로 생겼는지 알아보도록 하겠습니다.

useParams

기존에는 <Route>로 사용되지 않은 컴포넌트에서 match, location, history 객체에 접근하려면 withRouter HoC로 컴포넌트를 감싸줘야 했습니다.

// <= v5.0
function BlogPost({ match }) {
  const { slug } = match.params
  // ...
}

export default withRouter(BlogPost)

v5.1부터 useParams hook이 추가되면서 손쉽게 match.params 객체에 접근할 수 있게 되었습니다.

import { useParams } from 'react-router'
// >= v5.1
export default function BlogPost() {
  const { slug } = useParams()
  // ...
}

useHistory

useHistory hook을 사용하면 손쉽게 history 객체에 접근할 수 있습니다.

// <= v5.0
function BlogPost({ history }) {
  // ...
}
export default withRouter(BlogPost)


// >= v5.1
import { useHistory } from 'react-router'

export default function BlogPost() {
  const history = useHistory()
  // ...
}

useLocation

useLocation hook을 사용하면 location객체에 접근할 수 있습니다.

// <= v5.0
function BlogPost({ location }) {
  // ...
}
export default withRouter(BlogPost)


// >= v5.1
import { useLocation } from 'react-router'

export default function BlogPost() {
  const location = useLocation()
  // ...
}

useRouteMatch

useRouteMatchmatch객체의 값에 접근할 수 있게 해주는 hook입니다.

또한 인자로 <Route>컴포넌트의 프로퍼티들(path, strict, sensitive, exact)을 가진 객체를 받을 수 있으며, 만약 path프로퍼티와 현재 페이지의 URL이 일치할 경우 해당 pathmatch객체를 반환하고 일치하지 않을 경우 null을 반환합니다.

만약 아무 인자도 넘겨주지 않고 해당 hook을 호출하면 withRouter HoC로 match객체를 접근했을 때처럼 제일 가까운 부모 <Route>컴포넌트의 match값을 리턴합니다.

// 페이지의 url이 "/BLOG/:slug/"와 일치할 때 BlogPost 컴포넌트를 렌더링하고 싶은 경우

// <= v5.0
function App() {
  return (
    <div>
      <Route
        path="/BLOG/:slug/"
        strict
        sensitive
        render={({ match }) => {
          return match ? <BlogPost match={match} /> : <NotFound />
        }}
      />
    </div>
  )
}

// <= v5.1
import { useRouteMatch } from 'react-router'
function App() {
  const match = useRouteMatch({
    path: '/BLOG/:slug/',
    strict: true,
    sensitive: true
  })
  return <div>{match ? <BlogPost match={match} /> : <NotFound />}</div>
}

// 제일 가까운 부모 <Route>컴포넌트의 match객체에 접근 하고 싶은 경우

// <= v5.0
function BlogPost({ match }) {
  // ...
}
export default withRouter(BlogPost)

// >= v5.1
export default function BlogPost() {
  const match = useRouteMatch()
  // ...
}

Migration guide

react-router v5는 v4와 호환되게 개발되었기 때문에 기존 프로젝트에 react >= 16.8, react-router >= 4 버전을 사용하고 계셨다면 별다른 마이그레이션 작업 없이 react-router 버전을 올리실 수 있습니다.

만약 v5.1에 새롭게 추가된 기능들로 기존 소스들을 리팩토링 하고 싶으시다면 공식 블로그 글를 참고해주세요.

Reference

comment

Comments