포스트

리액트 맛보기 5일차

안녕하세요 🐸

리액트 맛보기 5일차 입니다!

01. react-router-dom

react-router-dom은 URL을 감지하고 화면에 보여질 페이지를 렌더링 하는 라이브러리 입니다 아래의 명령어로 손쉽게 설치 가능합니다

1
npm i react-router-dom

버전을 명시하지 않으면 최신 버전으로 설치가 되는데 작성일(2024-06-29) 기준으로는 6.23.1버전 입니다.
다만 제가 들었던 강의에서는 5.3.0 버전을 기준으로 했기 때문에 사용 방법에 대해 정리해보겠습니다.

공식 문서에서 나오는 예시를 먼저 보겠습니다.

아래 예시는 가장 기본적인 사용 예시입니다. 보다 다양한 기능이 있지만 모두 걷어내고 라우터 그 본연의 역할만을 하는 예시입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import * as React from "react"; 
import * as ReactDOM from "react-dom/client"; 
import { 
	createBrowserRouter, 
	RouterProvider, 
} from "react-router-dom";
import "./index.css"; 

const router = createBrowserRouter([
	{ 
		path: "/", 
		element: <div>Hello world!</div>, 
	}, 
]); 

ReactDOM.createRoot(document.getElementById("root")).render(
	<React.StrictMode> 
		<RouterProvider router={router} /> 
	</React.StrictMode> 
);

5버전과 대비대는 점은 Router RouterProvider를 사용한다는 점. 그리고 Switch와 BrowserRouter 대신 createBrowserRouter를 통해 라우터 변수를 생성하여 사용한다는 점 입니다.

path는 경로 URL을 의미하며 element는 렌더링될 컴포넌트를 의미합니다.
페이지를 보여줄 수 없는 경우에는 이를 대신할 에러 페이지를 설정할 수 있는데 이는 errorElement 으로 사용 가능합니다.

동적 URL을 사용하기 위해서는 :키이름 의 형식으로 path 내에 명시하여 사용할 수 있습니다.

01-1. loader, useLoaderData()

react-router-dom의 6버전에서 추가된 유용한 기능 중에는 loader 기능이 있습니다. 이는 미들웨어의 역할을 합니다.

개발할 때에 보통 URL 파라미터 등을 통해 화면이 처음 렌더링 될 때 useEffect()를 사용하여 최초에 API를 호출 하는 등의 행위를 합니다. loader는 컴포넌트가 랜더링 되기 전에 미들웨어 수준에서 이 작업을 수행하여 화면이 렌더링 되고 API 호출과 같이 초기 1회 이루어 지는 초기화 작업으로 인해 렌더링이 늦어지는 부분을 해결할 수 있습니다. 반대로 오히려 loader에서 너무 많은 작업을 수행한다면 렌더링 자체가 늦어지는 문제가 발생할 수 도 있습니다. 그렇기 때문에 중요도를 고려하여 설계하는 것이 중요하겠습니다.

사용 방법은 아래의 예제와 같습니다.

미들웨어 기능을 수행할 함수와 랜더링될 컴포넌트 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import axios from "axios";

import { useLoaderData } from "react-router-dom";
  

export async function loader({params}){

	const response = await axios.get(`https://yts.mx/api/v2/movie_details.json?movie_id=${params.id}`);

	return {response};

}

  

export function Detail() {
	const {response} = useLoaderData();

	const movie = response.data.data.movie;

	return (
		<div>
			<h1>movie.title</h1>
		</div>
	);
}

라우터 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import {
	createBrowserRouter,
	RouterProvider,
} from "react-router-dom";
import { Detail, loader as detailLoader } from "./routes/Detail";

//...생략
function App() {
	const router = createBrowserRouter([
		{
			path: "/movie/:id",
			element: (
				<Detail/>
			),
			loader : detailLoader
		},
	]);
	return (
		<RouterProvider router={router}/>
	)
}

미들웨어 기능을 수행할 함수 loader를 detailLoader로 가져와 loader에 이를 명시하여 미들웨어 기능을 하도록 합니다. 이때 loader에서 동적 URL에 사용되는 파라미터를 사용할 수 있습니다. 이후 미들웨어는 결과를 리턴하고 컴포넌트에서는 이를 사용할 수 있습니다.

컴포넌트는 useLoaderData()를 사용하여 loader에서 받은 값을 사용할 수 있습니다.

02. useParam()

동적 라우팅을 위해 URL에 :키 를 사용했을 때 이를 가져오는 함수 입니다.

위에서 설명한 loader와 userLoaderData()를 사용하지 않는다면 이를 통해 URL 내의 값을 가져와 컴포넌트 렌더링 후 최초 1회에 초기화 작업을 수행할 수도 있습니다.

03. gh-pages

깃허브에서 제공하는 정적 웹사이트 호스팅 서비스 입니다.
정적 웹사이트 호스팅이다 보니 주로 리액트, 뷰 프로젝트 배포용으로 사용되는 것 같네요

gh-pages 의 공식 문서에서는 Git 1.9이상, Node 14 이상을 필요로 하고 있다 명시하고있습니다.

npm 공식 문서에 사용 방법이 장황하게 있습니다. 하지만 저희가 찾아볼 부분은 아래의 링크 부분입니다.

gh-pages#Command Line Utility

03-1. 설치하기

gh-pages의 사용에 앞서 설치 명령어는 아래와 같습니다.

1
npm install gh-pages

03-2 .스크립트 설정하기

package.json 파일을 수정해야합니다.

homepage 값을 추가합니다.

1
2
3
4
{
"...":"...",
"homepage": "https://{깃허브이름}.github.io/{레포지토리이름}"
}

제 레포지토리의 예시를 들자면 아래와 같습니다.

1
2
3
4
{
"...":"...",
"homepage": "https://codingKermit.github.io/react"
}

script 영역에 아래와 같은 스크립트를 추가합니다.

1
2
3
4
5
6
7
{
	"...":"...",
	"scripts"{  
		"deploy" : "gh-pages -d build",
		"predeploy" : "npm run build"  
	}
}

pre~ 스크립트는 pre 키워드 뒤에 있는 이름의 스크립트가 실행되기 전에 실행됩니다. 즉, deploy 가 실행되기 전에 predeploy 가 실행됩니다.

gh-pages 를 통해 배포하게 되면 주어진 레포지토리에 gh-pages 라는 브랜치가 생성됩니다. 그렇기 때문에 혹시라도 branch already exists 에러가 발생한다면 브랜치를 확인해보시면 됩니다.

본인 레포지토리의 Actions 에서 빌드 결과를 확인해볼 수 있습니다. 성공적으로 빌드가 된다면 앞서 설정한 homepage 의 주소로 접속 시 작업한 페이지가 나옵니다.
적용 될 때 까지 10분 내외의 시간이 소요될 수도 있으니 커피 한잔 하시고 접속해보시면 됩니다.

03-3. 루트 경로 URL 맞추기

앞서 리액트에서 공부한 내용대로는 루트 URL을 설정하지 않았기 때문에 루트 경로(/) 로 이동하려 한다면 {깃허브이름}.github.io/{레포지토리}/ 로 이동이 됩니다.
react-router-dom 에서 루트 경로는 레포지토리 이름이 포함되지 않은 기본 경로이기 때문에 URL 매핑이 되지 않아 404 에러가 발생하게 됩니다.
그래서 basename 을 통해 루트 URL을 변경해줄 필요가 있습니다.

react-router-dom 공식 문서에서는 이를 basename을 통해 설정하도록 설명하고 있습니다. 공식 문서의 예제 코드입니다.

1
2
3
createBrowserRouter(routes, { 
	basename: "/app", 
});

여기서 routes는 앞서 우리가 작성한 path, element를 설정한 route 배열을 의미합니다.
제가 사용한 레포지토리 이름은 react 입니다. 이를 고려한 예제는 아래와 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  const router = createBrowserRouter([
    {
      path: "/",
      element: (
        <Home/>
      ),
    },
    {
      path: "/movie/:id",
      element: (
        <Detail/>
      ),
      loader : detailLoader
    },
  ],{
    basename:"/react" // `/` 로 접근시 `/react` 로 찾아가게됩니다.
  });

이렇게 설정해 놓으면 gh-pages로 배포한 프로젝트에서도 package.json에서 입력한 homepage와 일치하게 되어 정상 동작합니다.


gh-pages : https://www.npmjs.com/package/gh-pages
react-router-dom : https://reactrouter.com/en/main/routers/create-browser-router

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.