#4.0 Update Introduction(업로드 소개)

react-router-dom 버전6 업그레이드 가이드
강의는 5.3.4버전이고 현재 최신은 6버전인데 리액트의 철학이 바뀌었기에 차이가 상당하다.
그러므로 5.3.4버전으로 모든 강의를 다 시청하고 이 다음 강의로 돌아가서 시청하는 것을 추천!
5버전을 클래식 버전이라고 하는데 아직도 많은 사람들이 클래식 버전을 좋아한다.

npm I react-router-dom@5.3.4

먼저 BorowserRouter 대신 createBorowserRouter를 사용할 것이다.
한 번 비교해보자.
BorowserRouter

#4.2 createBrowserRouter

jsx 컴포넌트를 사용하지 않고도 브라우저를 좀 더 선언적으로 바꿔준다.
리액트 라우터 공식문서를 참고하면 잘 나와있다.

첫 번째 라우터는 전체 toute들의 컨테이너와 같은 역할을 할 것이다.


main.tsx에 RouterProvider를 import하고 export한 router를 props로 준다.
하지만 아직 화면에 컴포넌트들이 렌더링되지 않는다.


Outlet 컴포넌트를 root에 넣으면 된다.
Outlet는 필요한 경우 Home, About 등을 소환한다고 보면 된다.

#4.3 errorElement

에러 엘리먼트가 추가됐다.
컴포넌트에 에러가 발생해서 충돌하거나, 컴포넌트의 위치를 찾지 못할 때 쓴다.

이렇게 NotFound라는 컴포넌트를 만들고

“/”에 errorElement의 props로 NotFound를 넣는다.

그럼 잘못된 주소를 입력했을 경우 NotFound가 뜬다.

그리고 충돌하는 경우엔 이처럼 “/” 주소에 존재하지 않는 속성을 조회하는 등의 경우

이렇게 미리 에러 컴포넌트를 만들어두고

에러 컴포넌트를 적용한 다음 “/” 페이지에 가보면

이렇게 에러 컴포넌트가 뜬다. 여기서 Header가 표시되는게 중요한데 이게 무슨 뜻이냐면 컴포넌트들을 다른 컴포넌트에서 발생하는 문제로부터 보호해준다는 얘기다.

만약 errorElement를 적용하지 않으면

이런 페이지가 뜰 것이다.
즉, errorElement는 에러가 넘치지 않게 일종의 장벽을 만들어주는 것이다.

#4.4 useNavigate

useNavigate는 이전 버전의 useLocation.push, useHistory.push와 같은 역할이다.
다른 페이지로 이동시켜 준다는 것이다.
페이지를 이동하는데는 두 가지 방법이 있는데

  1. Link: 유저가 클릭
  2. useNavigate: 프로그램적으로 페이지를 이동(로그인 페이지로 이동시키기 등)

사용 예시:

const navigate = useNavigate();

// 특정 버튼 클릭 시 페이지 이동
const handleButtonClick = () => {
  navigate('/contact');
};

#4.5 useParams

빠르게 user의 db를 만들어보자.

Home에 링크를 만들고 해당 페이지로 이동한다.(에러엘리먼트가 잘 나온다)

페이지를 제대로 띄우기 위해 라우터에 User를 추가하고 확인하면

useParams가 주소의 params를 가져와서 잘 띄우는 것을 확인할 수 있다.


userId는 users에 있는 속성이 아닌 동적인 값이므로 []표기법을 사용하여 name를 가져온다.

그러면 정상적으로 출력 된다.

#4.6 Outlet


해당 스크린에 자식이 있다면 Outlet이 스크린의 자식을 render한다.

링크를 누르면 좌측 페이지에서 우측 페이지로 이동한다.
url 주소가 해당 컴포넌트의 하위 컴포넌트 주소로 바뀌면 Outlet이 해당 주소의 하위 컴포넌트로 바뀐다고 생각하면 된다.


모든 Outlet는 Route(이 경우엔 Root)의 자식들을 렌더했다.

  • Outlet:
    오른쪽 캡처의 children과 유사한 개념으로, 컴포넌트를 합성할 때 자신이 감싼 하위 컴포넌트의 위치를 정해주기 위해 사용
    즉, 오른쪽 캡처본처럼 Root 라우트의 하위에 Home, About, User 등의 하위 url이 있을 때, 주소가 /일 땐 Home, /about일 땐 About, /users/[id]일 땐 User 컴포넌트로 Outlet이 각각의 주소에 해당하는 컴포넌트로 변신한다고 생각하면 된다.

https://www.youtube.com/watch?v=0JbCa4yCqAM&ab_channel=%EB%94%A5%EC%94%A8%EC%BD%94%EB%8D%94

#4.7 useOutletContext

이전 시간에 어떻게 라우트가 그 자식들을 렌더하는지에 대해 배웠다.
<Outlet />, children, /:userId 등등

이제 이전 화면에서 데이터를 넘겨받는 것을 알아보자.

1. useParame을 사용하여 데이터를 url에 실어서 넘겨주기

2. 자식 라우트들과 소통하기

👉/users/followers에 유저 정보 보내기

function User() {
  const { userId } = useParams();
  return (
    <>
      <div>
        <h1>User: {users[Number(userId) - 1].name}</h1>
      </div>
      <hr />
      <Link to="followers">See followers</Link>
      <Outlet
        context={{
          nameOfMyUser: users[Number(userId) - 1].name, //유저 정보를 보내기
        }}
      />
    </>
  );
}

현재 <Outlet context={} />을 통해 User 라우트의 모든 자식들한테 유저정보를 보내고 있다.

function Followers() {
  const a = useOutletContext();
  console.log(a); //{nameOfMyUser: 'jun'}
  return <div>Followers</div>;
}

그리고 /users/:userId/followers에서 useOutletContext()<Outlet context={} />를 이용해 보낸 정보를 받을 수 있다.

왜 버튼 등을 만들지 않고 state만을 바꾼 것일까?
새로고침 등을 해도 유저들이 /users/1/followers에 있게 하기 위해서다. state를 사용하면 url에 state를 넣을 수 없다.
<Outlet context={} />, useOutletContext()를 사용하면 url을 이용해서 새로고침에도 정보가 초기화되지 않는다.

중요한게 하나 있다.

function Root() {
  return (
    <>
      <Header />
      <Outlet context={{darkMode: true}} />
    </>
  );
}

만약 <Outlet context={darkMode: true} />로 다크모드 정보를 전달한다고 해보자.
Outlet은 Root 화면의 자식들을 렌더한다는 것을 기억하자.
그 말은 Home, About, User 모두가 다크모드인지 아닌지 알게된다는 것이다.

#4.8 Extras

이제 리액트 라우터로 fetch와 form 제출도 가능하다.
하지만 라우터는 라우터인게 좋은 것 같다.

useSearchParams()

ex) localhost:8080/users?id=123
파라미터 수정, 읽기를 도와준다.
useSearchParams 훅 참고

리액트 라우터 공식문서
요점은 라우팅만 하는게 아닌 데이터 등도 로드하는 함수를 가진다는 것이다.

참고로 리액트 라우터를 만든 사람들과 리믹스를 만든 사람들은 같다.
그래서 리믹스의 아이디어를 리액트 라우터에 많이 적용하고 있다.
리믹스 프레임워크도 나중에 써보자.

profile
기록하자

0개의 댓글