6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Next.jsでRedux-toolkitをコピペだけでセットアップ

Posted at

半年ほど前に学んだRedux

当初は何をやっているのかさっぱり分からなかった

それでも諦めずにReduxと向き合い、今ではRedux無しでは開発できない体となってしまった。

ただ、毎回環境構築をして思うことがある。

「Reduxの環境構築面倒くさい。。。」

そこで、暇な時間にネットサーフィンをしていると、気になるパッケージを見つけた。

それがRedux-toolkit

今では、公式もRedux-toolkitを使うことをおすすめすると発表するほど素晴らしいパッケージ

Reduxのmiddlewareなどの複雑な環境構築を全て自動でやってくれる

そんなRedux-toolkitを更に、コピだけで環境構築を行えるようにします!!!!

特に細かい説明はしませんのでご了承下さい。

パッケージのインストール

npm i @reduxjs/toolkit react-redux redux-persist
npm i -D @types/react-redux

storeフォルダの作成

プロジェクト直下にstoreフォルダを作成してください。

また、他のフレームワークを使用している場合は公式ドキュメントにReduxをどこに格納すれば良いか書いてあると思うので、そちらを参照してください。

ストアの作成

先ほど作成した storeディレクトリにindex.tsを作成してください。

そして以下をコピペ

※ userSliceはこのあと作成するので消さないでください。

/store/index.ts
import {
    configureStore,
    getDefaultMiddleware,
    combineReducers,
    EnhancedStore,
} from '@reduxjs/toolkit'
import { loadingSlice } from './loading'
import {
    persistReducer,
    FLUSH,
    REHYDRATE,
    PAUSE,
    PERSIST,
    PURGE,
    REGISTER,
} from 'redux-persist'
import createWebStorage from 'redux-persist/lib/storage/createWebStorage'
import { userSlice } from './user'

// https://github.com/vercel/next.js/discussions/15687#discussioncomment-45319
const createNoopStorage = () => {
    return {
        getItem(_key) {
            return Promise.resolve(null)
        },
        setItem(_key, value) {
            return Promise.resolve(value)
        },
        removeItem(_key) {
            return Promise.resolve()
        },
    }
}
const storage =
    typeof window !== 'undefined'
        ? createWebStorage('local')
        : createNoopStorage()

const rootReducer = combineReducers({
    user: userSlice.reducer,
})


const persistConfig = {
    key: 'redux-toolkit-example',
    version: 1,
    storage,
}
const persistedReducer = persistReducer(persistConfig, rootReducer)

export const useStore = configureStore({
    reducer: persistedReducer,
    middleware: getDefaultMiddleware({
        serializableCheck: {
            ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
        },
    }),
})

export type RootState = ReturnType<typeof rootReducer>
export type AppDispatch = typeof useStore.dispatch

_app.tsxでReduxのプロバイダーでラッピングしてあげます。

/pages/_app.tsx
import { AppProps } from "next/app";
import { Provider } from "react-redux";
import { persistStore } from "redux-persist";
import { PersistGate } from "redux-persist/integration/react";
import { store } from "../store";

const CustomApp = ({ Component, pageProps }: AppProps): JSX.Element => {
    const persistor = persistStore(store);

    return (
        <Provider store={store}>
            <PersistGate persistor={persistor}>
                // コンポーネント
            </PersistGate>
        </Provider>
    );
};

export default CustomApp;

ユーザーのストアを作成

これでReduxを使える環境は整ったので、一例としてユーザーのストアを作成してみましょう。

/store/user/index.ts
import { createSlice, PayloadAction } from "@reduxjs/toolkit";

export type User = {
    username: string;
    email: string;
};

export type UserState = User;

export type UpdateUserPayload = User;

// 初期値
const initialState: UserState = {
    username: "Next.js",
    email: "next@gmail.com"
};

export type UpdateUser = {
    username: string;
    email: string
};

export const userSlice = createSlice({
    name: "user",
    initialState,
    // ユーザーのストアを変更する関数を定義
    reducers: {
        updateUser(
            state,
            action: PayloadAction<UpdateUser>,
        ) {
            return { ...state, ...action.payload };
        },
        reset() {
            return { ...initialState };
        },
    },
});

ここで、定義したユーザー情報を更新してみましょう。

/pages/index.tsx
import { useDispatch } from "react-redux";
import { AppDispatch } from "store";
import { userSlice } from "@/store/user"
 
const Home: React.FC = () => {
    const dispatch: AppDispatch = useDispatch();

    const updateUser = () => {
        dispatch(userSlice.actions.updateUser({ username: "React", email: "react@gmail.com" }))
    };
};

export default Home;

実際にローカルストレージを見れば、ストアの内容が変更されていることが確認できます。

注意事項

Dispatchの型定義は必ず行え

storeの中で非同期処理を行う場合、デフォルトのdispatchでは非同期処理を行うことが出来ません。

なので、/store/index.tsの中でAppDispatchを定義し、dispatchを使用する場合は面倒くさいのですが、必ずAppDispatchの型を指定してください。

かなり説明を端折ったので、分からに事があればコメント欄にてご質問ください。

以上、「Next.jsでRedux-toolkitをコピペだけでセットアップ」でした!

Thank you for reading

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?