Redux, RTK, React-router-dom Routing

정소현·2024년 8월 26일
0

React

목록 보기
9/12
post-custom-banner

Flux 아키텍쳐

  • Action: 애플리케이션에서 어떤 이벤트가 발생했음을 나타내는 객체
  • Dispatcher: 발생한 Action을 받아서 다른 요소들에게 전달하는 역할
  • Store: Action의 결과로 변경된 상태를 저장하는 공간
  • View: 사용자에게 데이터를 표시하고, 또 다른 Action을 트리거할 수 있는 UI

Flux와 Redux의 주요차이점

  1. Store의 역할 차이: Flux에서는 Store가 상태와 상태 갱신 로직을 모두 담고 있지만, Redux에서는 Store는 단순히 상태를 보관하며, 갱신 로직은 리듀서에서 처리
  2. Dispatcher 삭제: Reducer + Flux! 리듀서 함수가 상태를 관리하기 때문에 Redux는 단일 Store를 사용하며, Dispatcher가 따로 필요하지 않음
  3. 불변성 준수: Redux는 상태의 불변성을 강력하게 권장

🌟 Redux의 세 가지 원칙

  1. single Source of Truth
    : 모든 상태는 하나의 Store에 저장된다.
  2. State is Read- Only
    : 상태는 직접 변경할 수 없으며, Action을 통해서만 변경된다.
  3. Changes are Made with Pure Functions
    : 상태 변화는 순수 함수인 Reducer를 통해 이루어져야한다.

🌟 Redux Toolkit(RTK)

: Redux 로직을 작성할 떄 권장되는 방법, Redux의 복잡성을 줄이고 개발 효율성을 높이기 위해 만들어짐

보일러 플레이트

=> 최소한의 변경으로 여러곳에서재사용되며, 반복적으로 비슷한 형태를 띄는 코드를 뜻함

Redux Toolkit의 주요기능

1. ConfigureSTore

: Redux 스토어를 간단하게 설정하는 함수. 여러 리듀서를 결합
여러 미들웨어와 DevTools를 합칠 수 있게 해줌

2. createSlice

: Redux에서 state슬라이스를 관리하는 함수. 상태와 관련된 리듀서 및 액션생성자를 한곳에서 정의할 수 있고 불변성을 유지하며 상태를 업데이트할수 있또록 Immer라이브러리를 내부적으로 사용

Redux Toolkit을 사용하는 이유

  1. 코드 간소화 : 기조의 복잡한 Redux로직을 단순화할 수 있음
  2. 불변성 관리 : 복잡한 spread 문법을 사용하지 않아도 상태를 업데이트 할 수 있음
  3. 기본 제공 기능
    : Redux DevTools, thunk 미들웨어와 같은 필수 기능들을 기본적으로 포함하고 있음 추가적인 설정 없이도 Redux 개발 환경을 최적화할 수 있음!

Redux의 동작

Context와 Redux 의 차이

: Context는 업데이트할 때 Child에 있는 모든 컴포넌트를 다시 렌더링 하고

Redux는 딱 업데이트 된 부분을 리렌더링 사용해야한다.

🌟 React Router Dom

  • url에 해시(#)가 붙는 이유 (Hash Routing 사용 이유)
    1. 브라우저는 url에 #가 있으면 #포함 그 이후부터 페이지로 받아들이지 않는다.
    2. “http://example.com/#about”로 첫 랜딩 또는 새로고침이 되어도 브라우저는 역시 index.html 이라는 하나의 파일만을 로드한다.
    3. “http://exmaple.com/about”로 첫 랜딩 또는 새로고침이 되면 브라우저는 호스팅서버에 “/about”에 해당하는 별도의 페이지를 요청할 것이다. (404 Not Found)
    : React 애플리케이션에서 라우팅을 쉽게 구현하기 위한 라이브러리
    SPA에서 여러 페이지 간에 전환이 필요한 경우, URL에 따라 다른 컴포넌트를 렌더링 하는 역할을 함

라우팅의 두 가지 유형

  • 서버 사이드 라우팅 : 각 URL이 서로 다른 HTML 파일을 반환 (하드 Navigation)
  • 클라이언트 사이드 라우팅 : JavaScript로 페이지를 제어하여 부분적인 업데이트만 진행(소프트 Navigation)

클라이언트 사이드 라우팅의 두 가지 원리

  1. Path Fragment를 이용하는 방법
  2. history API를 이용하는 방법
    • 요즘은 이것을 많이 사용
    • history.pushState(). history.replaceState()를 통해 브라우저의 URL을 변경

☘️ history API를 이용하는 방법

(새로고침이 됨)

: 히스토리에 기록된 페이지 방문 이력을 따라 이동하는 것
뒤로 가기 효과 - back() 메서드
앞으로 가기 효과 forward() 메서드

History API go(), back(), forward() 모두 대체가능한 사용법

history.go(-2); // 뒤로 2번 가기
history.go(-1); // 뒤로 1번 가기
history.go(0); // 새로 고침
history.go(1); // 앞으로 1번 가기
history.go(2); // 앞으로 2번 가기

(새로고침이 되지 않음)

: 브라우저 주소 표시줄의 URL만 갱신되고 실제로 해당 페이지가 다시 불러오지는 않음

  • pushState()
    : 인자로 넘어온 URL을 현재 페이지의 바로 다음 방문 기록으로 추가, 이후에 방문 이력이 있다면 모두 지워버림
  • replaceState()
    : 인자로 넘어온 URL로 현재 페이지를 완전히 덮어 써버린다. 대신에 현재 페이지 다음에 있는 방문 이력을 건드리지 않는다.
    따라서 브라우저에서 뒤로가기 버튼을 누르면 원래 페이지의 이전 페이지로 이동하게 됨 , 아픙로 가기 버튼을 누르면 여전히 다음 페이지로 이동가능
  • PopStateEvent
    : 사용자가 브라우저에서 뒤로 가기나 앞으로 가기를 할 때 window 전역객체에서 발생 , 자바스크립트로 이벤트 핸들러를 걸어서 해당 URL에 부합하는 내용을 클라이언트에서 그려줄 수 있게 됨
  1. createBrowserRouter로 라우터 생성
    ex)
import { createBrowserRouter, RouterProvider } from "react-router-dom";

const router = createBrowserRouter([
  // 라우트 설정들
]);

function Routes() {
  return <RouterProvider router={router} />;
}

export default Routes;
  1. 공용라우트 (Public Routes)
    : 모든 사용자가 접근 가능한 페이지
  • 로그인 상태와 무관하게 항상 노출
const publicRoutes = [
  {
    path: "/about-us",
    element: <>About Us</>,
  },
  {
    path: "/read-me",
    element: <>Read Me</>,
  },
];Ï
  • 로그인 하지 않은 사용자
const routesForNotAuthenticatedOnly = [
  {
    path: "/",
    element: <PublicHome />,
  },
  {
    path: "/sign-in",
    element: <SignIn />,
  },
  {
    path: "/sign-up",
    element: <SignUp />,
  },
];
  • 인증된 사용자 전용 라우트, Protected Route 설정
    ProtectedRoute 컴포넌트
import { Navigate, Outlet, useLocation } from "react-router-dom";
import { useAuth } from "../provider/authProvider";
f
export const ProtectedRoute = () => {
  const { isSignIn } = useAuth(); // 아직 로직 없음
  const { pathname } = useLocation();

  if (!isSignIn) {
    return (
      <Navigate to="/sign-in" replace state={{ redirectedFrom: pathname }} />
    );
  }

  return <Outlet />;
};
post-custom-banner

0개의 댓글