동작 원리
- 브라우저를 켜서 처음 서버에 접속하면 routes컴포넌트의 지역 상태가 history.location 객체로 초기화. BrowserRouter가 props로 routes에게 history객체를 전달
- Link 태그를 클릭하거나 , 브라우저 액션(앞,뒤로 가기 등) 을 수행 함으로 현재 url을 변경 가능.
- History 객체를 이용한 구독 매커니즘 때문에 routes 컴포넌트의 location 객체가 새로운 것으로 변경.
- 이로 인해 routes 컴포넌트가 리렌더링 되고 그 결과 RouterContext의 값이 새로 구성되면서, 트리의 하위에 존재하는 각종 라우팅 관련 컴포넌트들이 리렌더링. → 현재 URL에 맞는 UI 렌더링
- 컴포넌트는 현재 URL과 path props 값을 다시 매칭 해서 match 객체, location 객체, history 객체를 렌더링 할 컴포넌트에게 전달
파일 라우팅하기 (feat. Next.js 라우팅 따라하기)
Next.js의 사용여부를 두고 가장 편하게 사용할 것 같았던 부분이 라우팅과 SSR부분이였다.
그러다가 Next를 사용하지 않고 React-route-dom을 사용하여 파일 라우팅을 한번 구현해보고 싶었고,
생각보다 내가 원하는 정보가 딱 없어서 직접 남김 ! 👍
원하는 최종 기능은 Next.js의 라우팅과 비슷하게 동작하는 것. 구현한건 아래와 같다.
/pages/test 로 들어오면 자동으로 pages폴더에 test폴더의 index를 불러오도록 했고,
/pages/test/10 같은 param이 더 있으면 Next와 같이 [:params].tsx 파일을 불러오게 했다.
일단 react-router-dom의 함수를 사용하려면 (useLocation) Route를 타야했기에…
BrowserRouter로 감쌌다. (다른 방법이 있으면 알려주세요!)
import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import Router from './router';
function App() {
return (
<div className="App">
<BrowserRouter>
<Router />
</BrowserRouter>
</div>
);
}
export default App;
그리고 아래의 코드가 내가 짠 파일 라우팅을 하기 위한 코드다! location을 가져와 약간의 가공(?)을 해주었다.
설명은 주석으로 대체하겠다.. (그런데 항상 느끼는거지만 막상 설명하려면 크게 할게 없네…😓)
import React, { createElement, useEffect, useState } from 'react';
import { useLocation } from 'react-router-dom';
function RouteComponent() {
const [component, setComponent] = useState(null);
const location = useLocation(); // 현재 경로 가져오기
useEffect(() => {
// example url: /test/10
// location.pathnam: "/test/10";
let paths = location.pathname.substring(1).split('/'); // [test, 10]
let componentPath = '';
// 불러올 파일 주소 만들어주기
paths.forEach(async (path: string, index: number) => {
componentPath += '/';
if (index === 0) {
// index.tsx
componentPath += path;
} else {
// [:params].tsx
const dynamicValue = path.substring(1);
componentPath += `[:params]`;
}
// 컴포넌트 불러오기
const { default: C } = await import(`./pages${componentPath}`);
setComponent(() => C);
})
}, [location])
return (
<div className='body-wrapper'>
{component && createElement(component)}
</div>
);
}
export default RouteComponent;
그리고 Next에서는 useParams 함수를 이용하여 url에서 정보를 받는데 해당 부분도 따로 hook폴더에
함수를 하나 만들어줬다. 해당 함수는 let [id] = useParam(); 요런식으로 사용하면된다.
import React from 'react';
import { useParams } from 'react-router-dom';
function useParam() {
// example url : /test/10
let originParams = useParams(); // {*: 'test/10}
let params = originParams['*']?.split('/').slice(1); // test는 제외하고 10만 리턴
return params ? params : [];
}
export default useParam;
.
.
.
아래 링크를 약간 참고하여 만들었다.
다만 해당 글에서도 결국 json array로 수동으로 적어줘야하는 부분을 좀 더 동적으로 만들어보고 싶었다.
좀 더 좋은 코드가 있으면 알고싶다…!!
https://tech.kakao.com/2022/07/13/active-routing-for-e-certificate/
깃허브 링크
https://github.com/dev-hyeonmin/react-base/commit/b4ab960c1e699091914a143fc46fab204e1584c6
'~ 2024.08' 카테고리의 다른 글
Error Log :: React 무한 루프에 갇혀버렸다. (0) | 2024.02.08 |
---|---|
Token 로그인 구현 (feat. 보안이 너무 어려웡🤔) (0) | 2024.02.01 |
Nest.js (0) | 2023.05.23 |
[Nest.js] Mailer Error :: Username and Password not accepted (0) | 2023.05.18 |
INDEX. (1) | 2023.01.18 |