🔧 Router은 모든 Router 컴포넌트의 인터페이스이며 기본적인 라우팅 관련 속성만 정의되어있다.
BrowserRouter
HashRouter
만약 여러개의 라우트가 존재한다면 Switch 컴포넌트로 감싸줘야한다.
<HashRouter>
<Switch>
<Route exact path="/" component={App}/>
<Route exact path="/price" component={Price}/>
</Switch>
</HahsRouter>
Route에서 exact path가 아니라면 두번째 컴포넌트로 가지 않고 첫번째 컴포넌트가 반복되어 나올수 있다.
<HashRouter>
<Switch>
<Route exact path="/item" component={App}/>
<Route path="/item/:id" component={itemDetail}/>
</Switch>
</HahsRouter>
V6 업데이트된 라우터
바뀐점
이제 존재하는 라우트들을 묶는 컴포넌트는 Switch 컴포넌트 대신 Routes 컴포넌트를 사용한다.
라우트의 component들은 element로 바뀌었다.
이제 app file에서 Router를 부르지 않는다.
function Router(){
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home/>} />
</Routes>
</BrowserRouter>
)
}
이것은 모든 React Router 웹 프로젝트에 권장되는 라우터다.
DOM History API 를 사용 하여 URL을 업데이트하고 기록 스택을 관리한다.
라우터들을 Array 형태로 관리 가능하게 해준다.
Router.tsx
const router = createBrowserRouter([
{
path:"/",
element:<Root />,
children:[
{path:"",element:<Home />},
{path:"about",element:<About />}
]
}
])
children을 설정하면 말 그대로 자신의 하위 path로 컴포넌트를 교환한다.
index.tsx
const rootNode = document.getElementById('root');
ReactDOM.createRoot(rootNode).render(
<React.StrictMode>
<RouterProvider router={router}/>
</React.StrictMode>,
);
Root.tsx
import {Outlet} from "react-router-dom";
function Root(){
return <div><Outlet/></div>
}
위에서 설정한 path 마다 바뀌는 컴포넌트는 부모(여기서는 Root) 안에 있는 Outlet 컴포넌트다.
만약 /about을 가는 경우 순서는 아래와 같다.
outlet은 router에서 children에 등록한 컴포넌트로 교체해주는 역할을 한다.
예를 들면 React에서 컴포넌트에서 인자를 받고 안에 children을 보여주는 것과 같다.
ex)
function Home({children}){
return <div>{children}</div> {/*<div><div>hihi</div></div>*/}
}
function Index(){
return <Home><div>hihi</div></Home>
}
react의 context api와 같다.
자식의 Outlet에 context를 보낼 수 있다.
import {Outlet} from "react-router-dom";
function Home(){
const a = 10;
return(
<div>
<Outlet context={{homeA : a}}/>
</div>
)
}
Outlet에 About이 들어간다면
function About(){
const ctx = useOutlerContext();
console.log(ctx) // {homeA: 10}
return <div><div>
}
Loader는 경로를 통해 요소에 대한 데이터를 렌더링하고 제공하기 전에 호출된다.
createBrowserRouter와 같은 데이터 라우터를 사용해야만 사용이 가능하다.
<Route
path="/teams/:teamId"
loader={({ params }) => {
return fetchTeam(params.teamId);
}}
/>;
로더에 대한 데이터를 받는 컴포넌트에서 사용하는 hook
const loadData = useLoaderData();
https://reactrouter.com/en/main/route/action
https://reactrouter.com/en/main/components/form
Form, fetcher, submit에서 라우트로 제출물을 보낼 때 호출된다.
createBrowserRouter와 같은 데이터 라우터를 사용해야만 사용이 가능하다.
action
request : 경로로 전송되는 Fetch Request 인스턴스.
가장 일반적인 사용 사례는 요청에서 FormData 를 구문 분석
params : 경로 매개변수는 동적 세그먼트에서 구문 분석되어 작업에 전달.
이것은 변경할 리소스를 파악하는 데 유용
<Route
path="/song/:songId/edit"
element={<EditSong />}
action={async ({ params, request }) => {
let formData = await request.formData();
return fakeUpdateSong(params.songId, formData);
}}
loader={({ params }) => {
return fakeGetSong(params.songId);
}}
/>
// /song/:songId/edit 에 있는 컴포넌트
// post form
<Form method="post" action="/songs" />;
// put form
<fetcher.Form method="put" action="/songs/123/edit" />;
// 필수적으로 제출
let submit = useSubmit();
// post form
submit(data, {
method: "delete",
action: "/songs/123",
});
// put form
fetcher.submit(data, {
method: "patch",
action: "/songs/123/edit",
});
Router.tsx
const router = createBrowserRouter([
{
path:"/",
element:<Root />,
children:[
{path:"",element:<Home />, errorElement: <ComponentError/>},
{path:"about",element:<About />},
{path:"user/:userId",element:<User />},
],
errorElement: <NotFound/>
}
])
에러 컴포넌트를 띄우는 경우
router로 설정한 path가 없는 곳으로 갔을 때 errorElement로 등록한 컴포넌트NotFound를 띄운다.
등록한 element가 에러를 내뱉을 때 ComponentError를 띄운다.
페이지를 이동할 때 react-router-dom에서 제공해주는 Link 대신에 useNavigate hook을 사용할 수 있다.
const navigate = useNavigate();
const goAbout = () => {
navigate("/about");
}
<div onClick={goAbout}>About</div>
user.tsx
export function User(){
const params = useParams()
return <div>{params.userId}</div>
}
현재 위치의 params의 값을 얻을 수 있다.
useState의 훅과 같이 사용한다.
const [readSerchParams, setSerchParams] = useSearchParams();
readSerchParams
현재 url에 있는 params의 값들을 읽을 수 있다.
ex)
?day=21&view=3
readSerchParams.get("day") => today
setSerchParams
params의 값을 set할 수 있다.
ex)
/
setSerchParams({day:21}) => /?day=21