フロントエンド開発といえば。
react アプリの初期化( npm init vite@latest <アプリ名> )

RTK Query

● RTK Queryのインストール

npm install @reduxjs/toolkit react-redux

● 作成するファイル

・src/providers/ReduxProvider.tsx
・src/stores/myApi.ts
・src/stores/store.ts

● ファイルの作成 1

src/providers/ReduxProvider.tsx

'use client';
import React from 'react';

import { store } from '../stores/store';

import { Provider } from 'react-redux';

export const ReduxProvider = (props: React.PropsWithChildren) => {
  return <Provider store={store}>{props.children}</Provider>;
};

● ファイルの作成 2

src/store.ts

import { configureStore } from '@reduxjs/toolkit';
import { myApi } from './myApi';
import { setupListeners } from '@reduxjs/toolkit/query';

export const store = configureStore({
  reducer: {
    [myApi.reducerPath]: myApi.reducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(myApi.middleware),
});

setupListeners(store.dispatch);

● ファイルの作成 3

src/stores/myApi.ts

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

type People = {
  name: string;
  height: string;
  mass: string;
};

export const myApi = createApi({
  reducerPath: 'myApi',
  baseQuery: fetchBaseQuery({ baseUrl: 'https://swapi.dev/api/' }),
  endpoints: (builder) => ({
    getPeople: builder.query<People, string>({
      query: (id) => `people/${id}`,
    }),
  }),
});

export const { useGetPeopleQuery } = myApi;

● 既存ファイルの修正

src/main.tsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';
import './index.css';
import { ReduxProvider } from './providers/ReduxProvider.tsx';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <ReduxProvider>
      <App />
    </ReduxProvider>
  </React.StrictMode>
);

● hooksを使ってデータ取得するサンプル

src/App.tsx

import './App.css';
import { useGetPeopleQuery } from './stores/myApi';

function App() {
  const { data, isLoading } = useGetPeopleQuery('2');

  return (
    <>
      <h1>sample</h1>
      {isLoading && <div>Loading...</div>}
      <div>{JSON.stringify(data)}</div>
    </>
  );
}

export default App;

● RTK Query の Middleware

エラーログを表示するミドルウェアを作成してみます。

src/middlewares/errorLogMiddleware.ts

import {
  Middleware,
  isRejectedWithValue,
  MiddlewareAPI,
} from '@reduxjs/toolkit';
import { FetchBaseQueryError } from '@reduxjs/toolkit/query';

type EventData = {
  eventCategory: string;
  eventAction: string;
  eventLabel: string;
};

export const errorLogMiddleware: Middleware =
  (_: MiddlewareAPI) => (next) => (action) => {
    if (isRejectedWithValue(action)) {
      const errorPayload = action.payload as FetchBaseQueryError;
      const errorData: string = errorPayload.data as string;

      // エラー情報からイベントデータを作成
      const eventData: EventData = {
        eventCategory: 'API Error',
        eventAction: errorPayload.status as string,
        eventLabel: errorData,
      };

      // エラーを表示
      console.error('● eventData');
      console.error(eventData);
    }

    return next(action);
  };

src/stores/store.ts

import { configureStore } from '@reduxjs/toolkit';
import { myApi } from './myApi';
import { setupListeners } from '@reduxjs/toolkit/query';
import { errorLogMiddleware } from '../middlewares/errorLogMiddleware';

export const store = configureStore({
  reducer: {
    [myApi.reducerPath]: myApi.reducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(myApi.middleware).concat(errorLogMiddleware),
});

setupListeners(store.dispatch);

その他参考 : https://qiita.com/7tsuno/items/2301a35283db7cd54df9
https://zenn.dev/snamiki1212/scraps/3c7190317c5e8f

No.2514
05/10 11:23

edit