SPA는 Single Page Application(싱글 페이지 애플리케이션)의 약어로 한 개의 페이지로 이루어진 애플리케이션이라는 의미입니다.
SPA의 경우 서버에 제공되는 페이지는 하나지만, 사용자에게 보여주는 페이지를 주소에 따라 다르게 보여주는 방식입니다.
하지만 프로젝트의 규모가 커질수록 자바스크립트 파일이 커지지만, 코드 스플리팅 방식(code splitting)으로 라우터를 파일별로 나눠서 용량을 분배할 수 있습니다.
React-Router 설치:
yarn add react-router-dom
npm install react-router-dom
<Components>})<BrowserRouter>
<Routes>
<Route path='/app1/:urls' element={<App1/>}></Route>
<Route path='/app2' element={<App2/>}></Route>
<Route path='/*' element={<App3/>}></Route> { /* exact 대체제 */}
</Routes>
</BrowserRouter>
/* 경로는 복수라우팅을 막습니다. 다시말해 /app1 , /app2 이외로 접근하는 url은 /* 경로로 향합니다.
import { Link } from "react-router-dom";
<Link to="/app1/hello">App1 로 변경</Link>
Link와 a태그의 차이점은 Link는 주소를 바꿀때 새로고침을 하지 않습니다. a 태그는 새로고침을 하기 때문에 컴포넌트의 state 값이 초기화될 수 있습니다. Single Page Application 을 구현할때, 값이 바뀌지 않고 부분 컴포넌트만 다시 불러와야하기 때문에 필요한 경우가 아니라면 Link 태그를 써주세요.
<Outlet/>)V5의 경우 내부 라우터의 경우 path를 ='/noticelist/newpost' 를 기재해 주어야하지만 , V6부터는 입력하지 않아도 앞에 자동으로 주소가 붙습니다. 만약 V5처럼 path를 ='/noticelist/newpost' 를 적어주면 , <NewPost/> 주소는 /noticelist/noticelist/newpost 로 연걸될것입니다.
<Routes>
<Route path='/noticelist' element={<NoticeList idstatus={getcookiestat} />}>
<Route path='/newpost' element={<NewPost idstatus={getcookiestat} />}></Route>
</Route>
<Route path='*' element={<NotFound />} />
</Routes>
Route 컴포넌트 내부에서 Route를 사용할 때 , 중첩 라우터에서 (내부 라우터) <Outlet/> 를 사용해서 레이아웃 설정이 매우 간단해졌습니다.
중첩 라우팅의 구성이 되면 Outlet을 통해서 상위의 컴포넌트를 레이아웃화 할 수 있습니다. </OutLet> 으로 하위 컴포넌트의 위치를 설정할 수 있습니다.
// NoticeList 컴포넌트 <div> <Outlet/> // NewPost 컴포넌트가 해당 위치에 설정됩니다. </div> <Routes> <Route path='/newpost' element={<NewPost idstatus={getcookiestat} />}> </Routes> // Outlet 이 싫다면 Routes , Route으로 설정하셔도 됩니다.
기존의 react-router-config가 useRoutes라는 Hook으로 변경되었습니다. 태그 방식이 아닌 Hook 으로 Route를 설정할 수 있습니다.
function App() {
const routers = useRoutes([
{path: "/*" , element: <App3/>},
{path: "app1/:urls" , element: <App1/>},
{path: "app2" , element: <App2/>}
]);
return routers;
}
useRouter()을 사용할 때 Router로 감싸줘야합니다.
<BrowserRouter>
<Router>
<App/>
</Router>
</BrowserRouter>
공식 문서에서는 <Route> 이나 useRouter() 를 사용하는것을 모두 권장하며 편한 코드를 사용하시면 될꺼같습니다.
V5 에서는 useHistory() Hook을 사용했지만 V6로 업데이트 되고나서 useNavigate()로 이름이 바뀌었습니다. 이름만 바뀌었을 뿐 기능은 비슷하다 생각하시면 됩니다. history.push와 history.replace 에서 명칭을 navigate로 바꿔주시면됩니다.
const nav = useNavigate();
const navreplace = () => {
nav('/app2' , {replace: true}); // Link와 기능이 같다.
nav('/app2' , { state }); // State를 사용한다면 값을 넣어주세요.
}
return(<div>
APP1 파일 params 값 = {urls} <br/>
<Link to="/app2">App2 로 변경</Link>
<button onClick={navreplace}>app2로</button>
<button onClick={() => nav(-1)}>이전으로</button>
<button onClick={() => nav(1)}>다음으로</button>
</div>)
nav 안에 숫자값을 -2 넣어주면 2번 뒤로가기가 실행됩니다.
http://localhost:3000/app1/paramsData
파라미터 값 : paramsData
// React Router V6
<Route path='/app1/:urls' element={<App1/>}></Route>
import { Link, useParams } from "react-router-dom";
const App1 = () => {
const { urls } = useParams();
return(<div>
APP1 파일 params 값 = {urls} <br/>
<Link to="/app2">App2 로 변경</Link>
</div>)
}
URL 파라미터를 사용할 때는 V6 기준으로 useParams 을 사용합니다.
path의 path='/app1/:urls' 의 :urls 값과 useParams 으로 받는 객체 변수명이 같아야합니다.
결과값:

쿼리는 location 객체에 들어 있는 search 값에서 조회할 수 있습니다.
import { Link, useSearchParams } from "react-router-dom";
const App2 = () => {
const [searchParams] = useSearchParams();
console.log(searchParams); // url 전체
console.log(searchParams.get('value')); // value 값 가져오기
console.log(searchParams.entries()); // 키와 값 동시에 가져오기
for (const entry of searchParams.entries()) {
console.log(entry);
} // for 전개로 파라미터 키와 값 추출
return(<div>
APP2 파일 <br/>
파라미터: {searchParams} <br/>
파라미터 값: {searchParams.get('value')} <br/>
<Link to="/app1/hello">App1 로 변경</Link>
</div>)
}
결과값 :

콘솔 내용 :