Route는 ‘경로' 라는 의미를 담고 있고, Routing은 ‘경로를 찾는 행위', Router는 Routing을 해주는 ‘도구’라고 할 수 있습니다. 웹 프론트엔드에서 Routing은 다른경로(url 주소)에 따라 다은 view(화면)를 보여주는 것을 의미합니다.
기존의 웹페이지에서는 html에 a태그를 통해 링크를 걸고, 화면에서 해당 링크를 클릭햇을 때 다른 html 페이지로 이동하는 방식으로 라우팅했습니다. 하지만 React에서는 다른 방식으로 라우팅을 구현해야 하는데,
리액트는 Framework가 아닌 Library이기 때문에 라우팅 기능이 내장되어있지 않습니다. 그래서 별도의 Library를 설치해서 라우팅을 구현해야 하고, CRA를 통해서 만들 웹 애플리케이션은 SPA
이기 떄문에 기본의 라우팅 방식과는 다르게 라우팅을 구현해야 합니다.
SPA
(Single Page Application) 는 페이지가 하나인 웹 애플리케이션입니다. 여기서 '페이지'란 html파일을 뜻하기 때문에, SPA는 html이 하나인 웹 애플리케이션을 의미합니다. 상반되는 개념으로는 html파일이 여러개인 MPA
(Multi Page Application)가 있습니다.
MPA는 html 파일이 여러 개라서 다른 페이지를 보여주고 싶을때, 해당 html 파일을 연결해 보여주는 형태로 페이지를 이동하는 기능을 구현할 수 있었습니다. 하지만 SPA는 html 파일이 하나이기 떄문에 하나의 html에서 경로(url)에 따라서 다른 UI를 보여주는 라우팅 기능이 필요하게 된것입니다.
BrowserRouter
컴포넌트로 전체를 감싸준다.BrowserRouter
컴포넌트로 자식 요소로 Routes
컴포넌트를 넣어줍니다.Routes
컴포넌트의 자식 요소로 Route
컴포넌트를 넣어줍니다.Router 컴포넌트를 구성하는 각각의 컴포넌트들은 어떤 역할을 할까요??
BrowserRouter
컴포넌트는 주소 변경에 대해 다양한 편의 기능을 제공해주는 컴포넌트입니다. 대표적인 기능으로는 페이지가 새로 고침 되지 않아도 주소 변경이 가능하게 하는 기능이 있습니다.Routes
컴포넌트는 여거 Route를 감싸서 그 중 규칙이 일치하는 라우트 단 하나만을 렌더링 시켜주는 역할을 합니다.Route 컴포넌트는 규칙을 설정할 수 있는 컴포넌트 입니다. Route 컴포넌트의 형식을 보면 html에서 사용한 태그의 형식과 유사하다는 것을 볼 수 있습니다. 예를들어, input 태그에서 type 속성을 사용했던 것처럼 Route 컴포넌트에서는 path와 element 속성을 사용하는 것을 볼 수 있습니다.
Route 컴포넌트에서 path는 경로를 설정하는 속성이고, element는 path 속성에서 설정한 경로로 이동했을때, 어떤 컴포넌트를 보여줄지 결정하는 속성이다.
Route
컴포넌트의 path 속성에 따라 화면에 그려줄 UI를 담은 컴포넌트를 import 합니다.Route
컴포넌트의 path 속성을 설정해 주고, 설정한 경로(url)로 이동했을때, 화면에 그려징 UI를 감은 컴포넌트를 element 속성에 설정합니다./
는 디폴트 값으로 경로가 지정되지 않은 경우와 같이 떄문에, url에서 아무런 경로를 지정해 주지 않은 경우에는Route
컴포넌트의 path 속성에서 /
을 찾아 일치하는 element의 컴포넌트를 그려주게 됩니다.
Routes 컴포넌트는 여러 Route를 감싸서 그중 규칙이 일치하는 라우트 단 하나만을 렌더링 시켜줍니다. 그렇다면 경로에 상관없이 보여주고 싶은 컴포넌트가 있다면 위와 같이 이 규칙에 포함되지 않도록 Routes 컴포넌트 밖에 위치시켜주면 됩니다. 이렇게 구현하게 되면 결과적으로 Nav와 Footer 컴포넌트는 특정 경로에 따라 보여지는 것이 아니라 어떤 경로가 오더라도 항상 화면에 보여지게 됩니다.
마지막 단계로 index.js에서 App 컴포넌트가 있는 위치에 Router 컴포넌트를 대체해 주는 것입니다.
react-router-dom 에서 제공하는 컴포넌트 중 Link 컴포넌트를 이용해 라우팅 기능을 구현할 수 있습니다. Router에서 여러 컴포넌트를 import해서 사용했던 것과 마찬가지로, react-router-dom 으로부터 Link 컴포넌트를 import해서 JSX 내부의 원하는 곳에 사용할 수 있습니다.
Link 컴포넌트의 형식을 보면 to 라는 속성에 /signup 이라는 경로가 적혀 있는 것을 볼 수 있습니다. 이를 통해 화면에서 회원가입이라는 글을 클릭하면 /signup 이라는 경로로 이동하게 되고, Route컴포넌트의 path 값 중 일치하는 경로를 찾아 해당 컴포넌트를 화면에 그려주게 됩니다.
만약 Link 컴포넌트는 사용하면 a 태그로 변환되는 것을 개발자 도구에서 확인할 수 있습니다. 그런데 왜 a 태그 대신 Link 컴포넌트를 사용할까요?
그 이유는. a 태그를 직접 사용할 경우 페이지 이동 시 서버로부터 매번 새로운 페이지를 요청해서 받아오게 됩니다. 그렇다면, 현재 화면에서 몇 가지만 바뀌어서 렌더링 되어야 하는 작업에서도 전체 화면을 매번 다시 렌더링하기 때문에 비효율적으로 종작하게 됩니다.
반면, Link 컴포넌트를 통해 변환된 a 태그는 실제 서버에 요청을 보내지 않고, 단지 url만 변경됩니다. 그래서 url의 변경을 react-router-dom이 인지하고, 실제 화면에서 바뀌어야 하는 부분만 새로 렌더링되기 때문에, a 태그를 직접 사용하는 것보다 효율적입니다.
하지만, 애플리케이션 내부에서 url을 통해 페이지를 전환해야 할 떄는 Link 컴포넌트를 이용해 효율적으로 이동할 수 있지만, 외부사이트로 이동할 떄는 할상 전체 페이지를 새로 받아와야 하기 때문에 a tag를 사용해야 합니다.
react-router-dom
에는 Link 컴포넌트 외에도 라우팅을 구현할 수 있게 해주는 hook
이 있습니다. 여기서 hook은 함수 컴포넌트에서 다루지 못했던 기능들을 구현할 수 있게 도와주는 함수입니다.
react-router-dom
에서 useNavigate
를 import 합니다.useNavigate
함수를 실행하고, 해당 함수가 반환한 결과를 navigate
라는 변수에 할당합니다. 여기서 useNavgate가 반환하는 값은 페이지를 이동하는 함수이기 때문에, navigate
변수는 페이지를 이동하는 함수가 됩니다.