半年ほど前に学んだ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はこのあと作成するので消さないでください。
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のプロバイダーでラッピングしてあげます。
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を使える環境は整ったので、一例としてユーザーのストアを作成してみましょう。
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 };
},
},
});
ここで、定義したユーザー情報を更新してみましょう。
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