이번 글에서는 React-Router-Dom 이 제공하는 Route 와 Link 컴포넌트를 이용해 props 를 전달하는 방법을 다뤄보려고 합니다. 개인적으로 이 문제를 해결하기 위해 여러 자료를 참고하고 오래 고민했었는데요. 코드스테이츠 크루님의 답변을 통해서 해결의 실마리를 잡을 수 있었고, 구상하던 대로 구현에 성공해서 3일만에 드디어 블로그에 정리를 하게 되었습니다.
Route 는 리액트 라우터 돔을 익히고 사용하기 위해서 알아야 할 가장 중요한 컴포넌트입니다. Route 컴포넌트는 path 라는 속성을 지정할 수 있고, 이 path의 속성값에 원하는 주소를 입력하여 Link 에서 연결하는 path 의 경로가 같을 때, 해당하는 Route 가 렌더되도록 합니다.
<Route exact path='/'>
<Home />
</Route>
<Route path='/about'>
<About />
</Route>
<Route path='/mypage'>
<MyPage />
</Route>
Route 의 기본적인 용법은 위와 같습니다. 주목해야 할 것은 Home 이라는 컴포넌트를 갖는 Route 의 path 앞에 exact 라는 다른 데에는 없는 구문이 하나 더 들어가있다는 점입니다. exact 는 리액트가 정확히 일치하는 주소를 만났을 때만 해당하는 경로의 컴포넌트로 연결하라는 뜻입니다. 만약 위의 코드에서 exact 가 없다면 리액트는 path 의 값이 '/'로 시작하는 모든 컴포넌트를 렌더링하게 됩니다.
Route 는 보통 Switch 와 함께 사용됩니다. Switch 로 묶어주고 내부에 여러 개의 Route 를 둘 경우 해당하는 Route 만을 렌더해주는 방식입니다.
<Switch>
<Route exact path='/'>
<Home />
</Route>
<Route path='/about'>
<About />
</Route>
<Route path='/mypage'>
<MyPage />
</Route>
</Switch>
이 경우에 Link 에서 path 를 연결하면, 컴포넌트가 위치한 구역에서 path 가 일치하는 Route 하위의 해당 컴포넌트를 바꿔가며(switch) 렌더링합니다. 쉽게 말해서, '/' 로 연결하면 <Home />, '/about' 으로 연결하면 <About />, 'mypage' 로 연결하면 <MyPage /> 를 개별적으로 렌더링한다는 것입니다.
리액트에는 props 라는 것이 있습니다. 부모 컴포넌트가 필요한 정보를 객체에 담아 보내면, 자식 컴포넌트에서 이를 받아 활용하는 것인데요. Link 컴포넌트도 이처럼 props 를 전달할 수 있습니다. 이 경우 Link 의 path에 연결된 해당 컴포넌트가 props 로 전달된 객체 내부의 정보를 사용할 수 있게 되죠.
<Link to={{
pathname:'/about',
state: {
id: 1,
name: 'eensungkim',
},
}}>
</Link>
Link 로 props 를 전달하기 위해서는 위와 같은 양식을 사용하면 됩니다. 기존에는 to='주소' 의 형태로 원하는 path 를 바로 연결했다면, 이제는 pathname: '주소' 로 연결합니다. 그리고 state: { 전달하려는 내용 } 의 형태로 props 를 전달하게 되죠. 그리고 전달받는 곳에서는 props.location.state 를 이용해 해당 정보에 접근할 수 있습니다. 예를 들어 name 에 접근하고 싶다면 props.location.state.name 이 되는 형태입니다.
근데 Link 를 통해 원하는 정보를 props 로 전달하기 위해서 선행되어야 하는 것이 있습니다. 바로 Route 의 수정입니다. 위에서 우리는 Route 컴포넌트 사이에 렌더링되어야 할 컴포넌트를 독립적으로 적어두었는데요. 이렇게 Route 를 구성하게 되면 Link 를 아무리 잘 작성해도 우리가 원하는 대로 state 내부의 props 가 전달되지 않습니다. 원하는 바를 구현하기 위해서는 Route 하위의 컴포넌트를 다음과 같이 재배치 시켜야 합니다.
<Switch>
<Route exact path='/' component={Home}></Route>
<Route path='/about' component={About}></Route>
<Route path='/mypage' component={MyPage}></Route>
</Switch>
<Route> 컴포넌트와 닫는 </Route> 사이에 독립적으로 자리했던 Home, About, MyPage 컴포넌트를 component 라는 속성을 이용해 Route 내부로 변경했습니다. 만약 이렇게 변경하지 않고 기존처럼 Route 바깥에 컴포넌트가 독립적으로 자리하고 있을 경우, Link 로 props 를 전달하고 싶어도 전달받는 쪽에서는 빈 객체만을 전달받게 됩니다.
알고나면 놀라울 만큼 간단한데 모를 때는 참 난감하기 그지 없는 Link 로 props 를 전달하는 방법이었습니다. Route 내부에 component 라는 속성과 그 값을 넣어 Route 를 연결할 수 있다는 것이 첫 번째, Link 는 첫 번째가 선행되어야 state 로 props 를 전달할 수 있다는 점이 3일 만에 알게 된 새로운 리액트의 용법이네요.