React-Router-dom

최정환·2021년 10월 27일
0

React

목록 보기
5/7

Router란

🔧 Router은 모든 Router 컴포넌트의 인터페이스이며 기본적인 라우팅 관련 속성만 정의되어있다.

  • BrowserRouter
  • HashRouter
  • MemoryRouter
  • NativeRouter
  • StaticRouter

BrowserRouter

  • HTML5기록 API를 사용하여 구성요소를 렌더링
  • 기록은 pushState과 replaceState를 통해 수정 가능
  • 동적인 페이지에 접합합니다.
  • 새로 고침시 경로를 찾지 못해 에러발생

HashRouter

  • 기본적으로 URL의 해시를 사용하여 구성 요소를 렌더링
  • 정적인 페이지에 사용하기 적합
  • 새로고침시 에러 x
  • 주소에 #이 붙음
  • 검색 엔진이 읽지 못 함

만약 여러개의 라우트가 존재한다면 Switch 컴포넌트로 감싸줘야한다.

  • Link to는 다른 곳에서 설정한 상태
<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 Router

V6 업데이트된 라우터

BrowerRouter

바뀐점

  • 이제 존재하는 라우트들을 묶는 컴포넌트는 Switch 컴포넌트 대신 Routes 컴포넌트를 사용한다.

  • 라우트의 component들은 element로 바뀌었다.

  • 이제 app file에서 Router를 부르지 않는다.

function Router(){
	return (
    <BrowserRouter>
      <Routes>
      	<Route path="/" element={<Home/>} />
      </Routes>
     </BrowserRouter>
    )
}


createBrowserRouter

이것은 모든 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을 가는 경우 순서는 아래와 같다.

  1. / 에서 Root을 렌더링한다.
  2. Root안에 있는 Outlet을 About 컴포넌트로 교환한다.


Outlet

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>
  }

useOutletContext

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

Loader는 경로를 통해 요소에 대한 데이터를 렌더링하고 제공하기 전에 호출된다.
createBrowserRouter와 같은 데이터 라우터를 사용해야만 사용이 가능하다.

<Route
  path="/teams/:teamId"
  loader={({ params }) => {
    return fetchTeam(params.teamId);
  }}
/>;

useLoaderData

로더에 대한 데이터를 받는 컴포넌트에서 사용하는 hook

const loadData = useLoaderData();


action

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",
});


Error Element

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/>
  }
])

에러 컴포넌트를 띄우는 경우

  1. router로 설정한 path가 없는 곳으로 갔을 때 errorElement로 등록한 컴포넌트NotFound를 띄운다.

  2. 등록한 element가 에러를 내뱉을 때 ComponentError를 띄운다.



useNavigate

페이지를 이동할 때 react-router-dom에서 제공해주는 Link 대신에 useNavigate hook을 사용할 수 있다.

const navigate = useNavigate();
const goAbout = () => {
	navigate("/about");
}

<div onClick={goAbout}>About</div>


useParams

user.tsx

export function User(){
  const params = useParams()
return <div>{params.userId}</div>
}

현재 위치의 params의 값을 얻을 수 있다.


useSearchParams

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



0개의 댓글