Link를 사용하려면 Router 안에서 사용해야함
Route는 React component고 path를 가짐
Switch 대신 Routes 사용
<BrowserRouter>
<Routes>
<Route path="/" element={<Home/>}>
<Route path="/about" element={<About/>}>
</Routes>
</BrowserRouter>
const router = createBrowserRouter()
우리의 Router를 array 형식으로 표현할 수 있게 해줌. 즉 JavaScript Object로 말임
첫번째 route는 Home 페이지가 아님.
대신 전체 route들의 컨테이너와 같은 것이 될거임.
먼저 우리가 할 것은 path를 정하는 거임
알겠지 ? 그 다음 만약 유저가 이 URL로 이동한다면 또는 만약 location이 그 URL과 일치한다면 우리는 element를 render할거야
Router.tsx
const router = createBrowserRouter([
{path:"/",
element:<Root/>,
},
]);
export default router;
RouterProvider라는 것을 render할거임. 이건 router라고 불리우는 prop을 가짐.
Index.tsx
import router from "./Router"
const root = ReactDom.createRoot(documnet.getElementById("root") as HTMLElement);
root.render(
<React.StrictMode>
<RouterProvider router={router}/>
</React.StrictMode>
);
path:"/"를 부모라고 생각하면 됨
Home이나 About은 자식으로 생각하면 됨
Router.tsx
const router = createBrowserRouter([
{path:"/",
element:<Root/>,
children: [
{path:"",
element:<Home/>,
},
{path:"about",
element:<About/>,
},
],
},
]);
export default router;
"/"는 URL 그자체임
"/about"은 일종의 "/"의 자식.
이게 우리가 about을 "/" 경로의 children 안에 넣는 이유야.
우리가 이제 뭘 해야하냐면 react-router-dom한테 말해줘야함
우리가 Root의 자식을 render하길 원한다! 고
Root.tsx
import {outlet} from "raect-router-dom";
function Root(){
return (
<div>
<Header/>
<Outlet/>
</div>)
};
}
export default Root;
내가 /about으로 가고자 하면, 넌 path:"/"와 매칭됨
그러면 react router는 Root를 Render하게 됨
근데 Root한테는 자식이 있기 때문에 우리는 Outlet이라는 컴포넌트를 사용했음
react router는 이 Outlet component를 통해서 URL을 보게 되는데
예를들어 /about이라면 Root를 render하고 About도 render하게 됨
즉 Outlet을 내가 render하고자 하는 route로 바꿔서 render한거야
우리는 About을 render하고 있는데, 그건 Root안에서 render되고 있음
이제 about 같은 경우 이 이 되는거와 같음
우리의 컴포넌트에 에러가 발생해서 충돌하거나, 컴포넌트의 위치를 찾지 못할 때 쓰는거임
NotFound.tsx
function NotFound() {
return <h1>404 Not found.</h1>;
}
export default NotFound;
Router.tsx
const router = createBrowserRouter([
{path:"/",
element:<Root/>,
children: [
{path:"",
element:<Home/>,
errorElement:<ErrorComponent/>,
},],
errorElement:<NotFound />,
},]);
Root element path에 에러를 추가할 수 있음
ErrorComponent.tsx
function ErrorComponent() {
return <h1>This component crashed</h1>;
}
export default ErrorComponent;
ErrorComponent가 멋진 이유는 다른 컴포넌트들을 또 다른 컴포넌트에서 발생하는 문제로부터 보호해주기 때문임
예를 들어 Home이 충돌하는게 끝나면 문제가 더 이상 넘쳐서 퍼져나가지 않도록 해서
내가 About page를 보는걸 막지 않을거임
errorElement를 모든 route들에 다 적용할 수 있음
Home 컴포넌트가 충돌하면, 우리는 일종의 에러 정벽을 만들어
보다시피 에러가 포함되어 있고 우리는 여전히 About page로 이동가능함.
유저를 어딘가로 보내는 기능
유저를 이동시키고 위치를 바꿔줌
다른 페이지로 이동시키는 한 가지 방법은 Link를 이용하는거임
Link는 유저가 클릭을 해야됨
만약 네가 유저를 로그인 시키거나 홈페이지로 이동시키고 싶다면,
프로그램적으로 유저를 페이지에서 없애버리고 싶다면, useNavigate를 쓰면 됨
const onAboutClick = () => {
navigate("/about");
};
<button onClick={onAboutClick}>About</button>
유저가 로그인해서 redirect 시키고 싶거나, 유저가 어떤 페이지로 갔는데 접근 권한이 없거나 했을 때 useNavigate를 쓰면 됨!
ver 5 에선 location.push.
리액트에서 라우터 사용 시 파라미터 정보를 가져와 활용하고 싶을 때
{
path: "users/:userId",
element: <User />,
},
콜론이 들어야가함 !
URL에서 userId 값이 뭔지를 알아내야함
왜냐면 보통 너의 react app에서 너는 id가 1을 가진 유저를 DB에서 검색해서 정보를 더 얻길 원할거니까
이제 이 유저 화면으로 와서 useParams를 할거야.
function User() {
const { userId } = useParams();
return (
<h1>
User with id {userId} is named: {users[Number(userId) - 1].name}
</h1>
);
}
모든 Outlet component는 Route의 자식들을 render 했었어
/를 쓰면 절대 경로
/를 쓰지 않으면 상대 경로 즉 지금 내가 현재 있는 그 경로 다음에 경로가 추가 될거임!
User.tsx
import { Link, Outlet, useParams } from "react-router-dom";
import { users } from "../../db";
function User() {
const { userId } = useParams();
return (
<div>
<h1>
User with id {userId} is named: {users[Number(userId) - 1].name}
</h1>
<hr />
<Link to="followers">See followers</Link>
<Outlet />
</div>
);
}
export default User;
Followers.tsx
function Followers() {
return <h1>Followers</h1>;
}
export default Followers;
Router.tsx
{
path: "users/:userId",
element: <User />,
children: [
{
path: "followers",
element: <Followers />,
},
],
},
User를 render하면서 followers도 User 화면 안의 Outlet에 넣을거임
라우터가 2개나 필요하지않아 그냥 자식을 정의하면 됨! followers가 User 화면의 자식이라는 것만 알려주면 됐었음 그리고 Outlet을 render하면 됨
자식 route들과 소통해보기
Outlet을 render할 거고, context라는 것도 send 할거임
여기에 네가 원하는 것 무엇이든지 보낼 수 있어
<Outlet
context={{
nameOfMyUser: users[Number(userId) - 1].name,
}}
/>
우리는 context를 Outlet을 통해서 보내고 있음
그러면 다른 쪽에서 받을 수 있음.
Followers.tsx
import { useOutletContext } from "react-router-dom";
interface IFollowersContext {
nameOfMyUser: string;
}
function Followers() {
const { nameOfMyUser } = useOutletContext<IFollowersContext>();
return <h1>Here are {nameOfMyUser}의 followers</h1>;
}
export default Followers;
Outlet은 Root 화면의 자식들을 render 한다는 것 말이야
이 hook은 네 search parameter를 수정하게 도와줌
또는 네 URL에서 search parameter를 읽어내는 걸 도와주지
이것들이 search parameter야
useSearchParams hook을 써보자
이걸하면 array를 하나 제공해
그리고 array의 첫번째 item은 search parameter를 읽기 위한 것이야
그리고 다른 것은 search parameter를 set하기위한 함수야