[공식문서 보는 방법]

1. 왜 써야하는지?

2. Getting Started 훝어보기 (기능을 보면서 큰그림을 보기 => 외울 필요는 없다)

3. 프로젝트에서 참고한다.

 

 

> 왜 써야하는가?

SPA 장점을 활용하면서 History 사용하기 위해서 React-router 를 사용한다.

> Getting Started

중첩경로 (레이아웃), 로더(데이터 로딩), NavLink 의 활성 링크, action?, redirect, defer, 낙관적 UI

 

> Project

 

App.jsx

import { createBrowserRouter, RouterProvider } from "react-router-dom";
import Home from "./pages/Home";
import NotFound from "./pages/NotFound";
import Videos from "./pages/Videos";
import Root from "./pages/Root";
import VideoDetail from "./pages/VideoDetail";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <NotFound />, // 에러페이지
    children: [
      {
        index: true,
        element: <Home />,
      },
      {
        path: "/videos",
        element: <Videos />,
      },
      {
        path: "/videos/:videoId",
        element: <VideoDetail />,
      },
    ],
  },
]);

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

export default App;

 

Root.jsx  => Outlet

import React from "react";
import { Outlet } from "react-router-dom";
import Navbar from "../components/Navbar";

const Root = () => {
  return (
    <div>
      <Navbar />
      <Outlet />
    </div>
  );
};

export default Root;

 

Navbar.jsx  => Link

import React from "react";
import { Link } from "react-router-dom";

const Navbar = () => {
  return (
    <nav>
      <Link to="/">Home</Link>
      <Link to="/videos">Videos</Link>
    </nav>
  );
};

export default Navbar;

 

Videos.jsx  => useNavigate

import React, { useState } from "react";
import { useNavigate } from "react-router-dom";

const Videos = () => {
  const [text, setText] = useState();
  const navigate = useNavigate();
  const handleChange = (e) => {
    const value = e.currentTarget.value;
    setText(value);
  };
  const handleSubmit = (e) => {
    e.preventDefault();
    navigate(`/videos/${text}`);
    setText("");
  };
  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input type="text" placeholder="video id: " value={text} onChange={handleChange} />
      </form>
    </div>
  );
};

export default Videos;

 

VideoDetail.jsx  ==> useParams

import React from "react";
import { useParams } from "react-router-dom";

const VideoDetail = () => {
  const { videoId } = useParams();

  return <div>VideoDetail {videoId}</div>;
};

export default VideoDetail;

 

반응형

'Frontend' 카테고리의 다른 글

RTK Query 란?  (0) 2023.04.13
[Vue3] Vue + Vite + Typescript 초기세팅  (0) 2023.03.23
  • RTK 쿼리란 무엇이며 어떤 문제를 해결합니까?
  • RTK 쿼리에 포함된 API
  • 기본 RTK 쿼리 사용

기존:

- 보여줄 부분은 빠르게 보여줘야함

- 로드 상태 추적 필요 (로딩중...)

- 동일한 데이터 중복 요청 방지

- 캐시 수명 관리

 

Redux:

- 로드상태 추적에 효율적

- 요청 생명주기에 따라 Dispatch 

- Redux Toolkit의 createAsyncThunkAPI 는 위 2가지를 추상화

- But, 로딩상태 또는 캐시된 데이터 관리가 어려움

=> React 커뮤니티에서는 데이터 패칭 및 캐싱상태관리와 다른 관심사로 여겨짐

 

 

RTK Query ?

Redux Toolkit 패키지에 포함된 데이터 캐싱 도구

 

[언제 RTK-Query 를 사용해야할까?]

- Redux 앱이 이미 있고 기존 데이터 패칭 로직을 ​​단순화하고 싶을때
- Redux DevTools 를 사용하여 상태 변경 기록을 보고싶을때
- React 외부에서 앱의 로직을 작동하고 싶을때

 

Apollo Client, React Query, Urql, SWR 등 에서 API 디자인에 고유한 접근 방식을 추가하였다.

다른 Tool 들과의 비교

 

 

[RTK Query 의 특징]

- 데이터 패칭 및 캐싱 논리는 Redux Toolkit 의 createSlicecreateAsyncThunk API 에서 구축된다.

- UI에 구애받지 않는다. => 모든 UI 레이어에서 사용 가능

- API 엔드포인트는 arguments 로부터 쿼리 query parameters 를 생성하고
   캐싱을 위해 응답을 변환하는 방법을 포함하여 미리 정의된다.

- 아래 3가지의 리액트훅을 생성할 수 있다.
   전체 데이터 패칭 프로세스를 캡슐화
   data 와 isLoading 구성요소를 제공
   mount / unmount 시 데이터 생명주기 관리

- initial data fetching 후 websocket 메시지를 통해 캐시 업데이트를 스트리밍하는 것과 같게 하는 cache entry lifecycle 옵션 제공

- TypeScript 로 작성됨

 

 

[포함된 API]

- createApi() : RTK 쿼리 기능의 핵심으로, endpoint 집합이라고 할 수 있다. 기본 URL 당 하나의 API 슬라이스 원칙으로 한다.

- fetchBaseQuery() : fetch 요청을 단순화하기 위한 작은 래퍼, createApi 에서 baseQuery 를 권장한다.

- <ApiProvider /> : Redux store 의 provider 가 없는 경우에 (대신) 사용할 수 있다.

- setupListeners() : RefetchOnMount 및 RefetchOnReconnect 동작을 사용하도록 설정하는데 사용되는 유틸리티

 

[번들 사이즈에 관하여..]

  • If you are using RTK already: ~9kb for RTK Query and ~2kb for the hooks.
  • If you are not using RTK already:
    • Without React: 17 kB for RTK+dependencies+RTK Query
    • With React: 19kB + React-Redux, which is a peer dependency

 

[RTK QUery 사용법]

1. createApi 를 import 하는 2가지 방법

import { createApi } from '@reduxjs/toolkit/query'

/* React-specific entry point that automatically generates
   hooks corresponding to the defined endpoints */
import { createApi } from '@reduxjs/toolkit/query/react'

 

2. createApi 의 사용

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import type { Pokemon } from './types'

// base URL 과 엔드포인트들로 서비스를 정의한다.
export const pokemonApi = createApi({
  reducerPath: 'pokemonApi',
  baseQuery: fetchBaseQuery({ baseUrl: 'https://pokeapi.co/api/v2/' }),
  endpoints: (builder) => ({
    getPokemonByName: builder.query<Pokemon, string>({
      query: (name) => `pokemon/${name}`,
    }),
  }),
})

// 정의된 엔드포인트들을 기반으로 export (use_____Query)
export const { useGetPokemonByNameQuery } = pokemonApi

 

3. Store 의 구성

import { configureStore } from '@reduxjs/toolkit'
import { setupListeners } from '@reduxjs/toolkit/query'
import { pokemonApi } from './services/pokemon'

export const store = configureStore({
  reducer: {
    // 생성된 리듀서를 최상위 레벨의 구체적인 슬라이스로 추가한다.
    [pokemonApi.reducerPath]: pokemonApi.reducer,
  },
  // 미들웨어를 추가하면 캐싱, 무효화, 폴링 등 사용 가능
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(pokemonApi.middleware),
})

// Optional
// refetchOnFocus/refetchOnReconnect 동작에 필요한 경우 'setupListeners' 문서 참조 (두번째 arg에 콜백함수)
setupListeners(store.dispatch)

 

4. react-redux 의 Provider 사용

import React from "react";
import ReactDOM from "react-dom/client";
import { Provider } from "react-redux";
import { store } from "./store";
import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement);
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

* Provider 나 ApiProvider 중에 하나만 사용해야한다. (충돌 위험)

ApiProvider 사용법에 대한 공식문서

 

 

5. 컴포넌트에서의 Hook 사용

import * as React from 'react'
import { useGetPokemonByNameQuery } from './services/pokemon'

export default function App() {
  // 1번 방법: 쿼리 훅을 사용해 자동으로 데이터를 가져오고 쿼리 값을 반환
  const { data, error, isLoading } = useGetPokemonByNameQuery('bulbasaur')
  
  // 2번 방법: 생성된 엔드포인트 아래의 개별 훅에 액세스할 수도 있다
  // const { data, error, isLoading } = pokemonApi.endpoints.getPokemonByName.useQuery('bulbasaur')
  
  // data 와 loading 을 기반으로 UI 를 렌더한다.
}

 

 

 

 

Reference:

https://redux-toolkit.js.org/rtk-query/overview#configure-the-store

 

 

 

 

 

 

 

반응형

'Frontend' 카테고리의 다른 글

React Router  (0) 2023.04.17
[Vue3] Vue + Vite + Typescript 초기세팅  (0) 2023.03.23

 

vite 를 사용하여 프로젝트 생성

npm create vite@latest

 

- 프로젝트명 입력하고 프레임워크는 vue, variants 는 typescript 로 세팅 

해당 폴더로 cd 이동 후 npm 설치

npm install

 

 

이외 필요한 라이브러리도 설치한다.

vue-router

npm install vue-router@4

https://next.router.vuejs.org/installation.html

 

vuex

npm install vuex@next --save

https://next.vuex.vuejs.org/installation.html

 

@types/node

npm install --save @types/node

 

 

 

vite-env.d.ts 파일에 아래 내용 추가

/// <reference types="vite/client" />

declare module "*.vue" {
  import type { DefineComponent } from "vue";
  const component: DefineComponent<{}, {}, any>;
  export default component;
}

 

vite.config.ts 파일에 @설정 추가

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import * as path from 'path' // 라이브러리 : @types/node

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@/': path.resolve(__dirname, './src') + '/'
    }
  }
})

 

혹시라도 vetur 익스텐션 때문에 에러가 난다면 프로젝트 바로 아래 vetur.config.js 파일을 추가해서 설정을 false 로 모두 변경한다.

// vetur.config.js
module.exports = {
  settings: {
    "vetur.completion.autoImport": false,
    "vetur.experimental.templateInterpolationService": false,
    "vetur.validation.interpolation": false,
    "vetur.validation.template": false,
    "vetur.validation.templateProps": false,
    "vetur.validation.style": false,
    "vetur.validation.script": false,
    "vetur.format.enable": false,
    "vetur.ignoreProjectWarning": true,
    "vetur.languageFeatures.codeActions": false,
    "vetur.languageFeatures.semanticTokens": false,
    "vetur.languageFeatures.updateImportOnFileMove": false,
    "vetur.trace.server": "off",
    "vetur.underline.refValue": false,
  },
};

 

 

 

이제 실행 시, 5173 포트로 초기화면을 볼 수 있다.

npm run dev
반응형

'Frontend' 카테고리의 다른 글

React Router  (0) 2023.04.17
RTK Query 란?  (0) 2023.04.13

+ Recent posts