redux-toolkit初期設定(NextJS水和物使用)


Redux-toolkitをNextJSプロジェクトに適用し、初期設定と簡単な使い方を整理する時間があります.SSRのNextJSプロパティを使用すると、Server Redux StoreとClient Redux Storeが別々に作成されるので、マージされた水和物ジョブの設定を試みます.
redux
redux-logger // 선택!
react-redux
next-redux-wrapper
@types/react-redux
@types/redux-logger // 선택!
@reduxjs/toolkit

createSlice

createSliceは、減速機を作成する従来の方法で動作タイプを自動的に設定したり、ステータス管理のためにインスタントメッセージを内蔵したりするなどの便利な機能を提供しています.
従来のreduceを分離する方式とは異なり、正式な書類は、sliceを特徴内で状態ドメインユニットに分割することを決定することができる.
import { createSlice, PayloadAction } from "@reduxjs/toolkit";

const counterSliceType = "slice/counter";

export interface ICounterState {
	value: number;
}

const initialState: ICounterState = {
	value: 0
}

const counterSlice = createSlice({
	initialState,
    name: counterSliceType,
    reducers: {
    	increase: (state) => {
        	state.value += 1;
        },
        increaseByAmount: (state, action: PayloadAction<number>) => {
        	state.value += action.payload;
        }
    }
})

export const { increase, increaseByAmount } = counterSlice.actions;
export default counterSlice;

  • InitialState:Reduserの初期値

  • name:スライスを識別する文字列値
    以降生成されるreduce動作タイプのprefix
    ex: slice/counter/increase, slice/counter/increaseByAmount

  • Reducers:Redux-toolkitはReducers内部でimmerを使用することをサポートしているので、単独でインストールする必要がなく、可変コードで不変の状態管理が可能
  • FSA


    カニの動作は、簡単なパラメータを直接返すよりも、特定の論理を処理した後にreduceによって処理される方法を使用します.createSliceでは、FSAは、以下の呼び出し呼び出しprepareによって使用することができる.
    const counterSlice = createSlice({
    	...
        reducers: {
        	...
            decrease: {
            	reducer: (state, action: PayloadAction<number>) => {
                	state.value -= action.payload;
                },
                prepare: () => {
                	return {
                    	payload: Math.random()*100 // 사용자 정의 값을 payload로 반환함
                    }
                }
            }
        }
    })

    RootReducer


    Reduserは目的に応じて複数生成できるので、複数のReduserをマージするために、以前に使用したcombineReducersを使用した.
    また、next-redux-wrapperが提供するHYDRATEにより、サーバとクライアントの状態が統合される.
    interface RootStates {
    	counter: ICounterState;
    }
    
    const rootReducer = (
    	state: ReducerStates,
        action: AnyAction
    ): CombinedState<ReducerStates> => {
    	
        switch(action.type) {
        	case HYDRATE:
            	return action.payload;
            default: {
            	const combinedReducer = combineReducers({
                	counter: counterSlice.reducer
                })
                return combinedReducer(state, action);
            }
        }
    
    }
    次に、rootReducerに特定の構成部品でアクセスし、そのタイプを決定して、必要なステータス値を使用します.export type RootState = ReturnType<typeof rootReducer>;

    store

    next-redux-wrapperは、SSRの特性に基づいて、サーバ側で生成されたリカバリポイントとクライアント側で生成されたリカバリポイントを統合する操作であり、これらの操作により、NextJSが提供するgetInitionalPropsなどの方法でリカバリポイントのハチミツのようなライブラリにアクセスすることができます.next-redux-wrapperは、リポジトリを作成する関数によってルート構成部品を高次構成部品(HOC)にラップする.
    redux-toolkitはstoreの作成に新しい方法を提供し、既存のreduceコアメソッドcreateStoreconfigureStoreと抽象化し、以下の形式で記述します.
    // store 만들기
    // store.ts
    const store = configureStore({
    	reducer: rootReducer as Reducer<CombinedState<ReducerStates> AnyAction>,
        devTools: process.env.NODE_ENV === 'development',
    });
  • 減速機:使用する減速機を使用し、シート上のダブルナイフからなるコンビネーション型減速機で生成されるルート型減速機.
  • devTools:既存のredoxで、reduce開発者ツールをミドルウェアで挿入する場合、rtkはブール値として選択できます.
  • 中級は基本的にredux-thunkを内蔵しており、単独で所望の中級を入れるために、アレイに中級を追加する形として以下のgetDefaultMiddlewareを用いる.middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(customMiddleware)
  • ショップが作成された以上、ショップに戻る関数を作成し、next-redux-wrapperによって提供されるcreateWrapperによってパッケージを作成して高次関数を提供することができます.
    const makeStore = () => {
    	const store = configureStore({
        	...
        });
        return store;
    }
    
    const wrapper = createWrapper(makeStore);
    export default wrapper;
    パッケージで提供されるwithRedux高次関数を使用して_app.tsx要素をラップ
    // _app.tsx
    
    function MyApp(...) {
    	return ..
    }
    
    export default wrapper.withRedux(MyApp)
    これで全体のRedux設定は終了です

    試用する

    // pages/index.tsx
    
    import type { NextPage } from "next";
    import styled from "styled-components";
    import { useDispatch, useSelector } from "react-redux";
    import { RootState } from "src/redux/reducers";
    import {
      increase,
      increaseByAmount,
      decrease,
    } from "src/features/counter/counterSlice";
    
    const Home: NextPage = () => {
      const dispatch = useDispatch();
      const counter = useSelector((state: RootState) => state.counter.value);
    
      const increaseCount = () => {
        dispatch(increase());
      };
    
      const increaseCountByAmount = () => {
        dispatch(increaseByAmount(Math.random() * 100));
      };
    
      const decreaseCount = () => {
        dispatch(decrease());
      };
    
      return (
        <Wrapper>
          <div>{counter}</div>
          <button onClick={increaseCount}>+1</button>
          <button onClick={increaseCountByAmount}>+increase</button>
          <button onClick={decreaseCount}>-decrease</button>
        </Wrapper>
      );
    };
    
    export default Home;
    
    const Wrapper = styled.div``;

    createAsyncThunk

    createAsyncThunkによる非同期アクションの作成と使用createAsyncThunkによって生成された動作は、createSliceの減速機内部で使用されるのではなく、外部リーダextraReducerにおいて使用が宣言される.extraReducerは、書込createReducerのように使用することができ、RTKでは2つのマーキング法(Map Objectマーキング法、Builderマーキング法)から選択することができ、ここではジェネレータシンボルを用いて記述する.createAsyncThunkは、動作を識別する最初のstring値である.
    2番目のパラメータは、実行するアクションロジックを記述することができます.
    export const asyncCounter = createAsyncThunk(
    	'asyncCounter',
        async() => {
        	const result = await new Promise((resolve, _) => {
            	setTimeout(() => {
                	resolve(Math.random()*100);
                }, 1000);
            })
            return result;
        }
    )
    
    const counterSlice = createSlice({
    	...
        extraReducers: (builder) => {
        	builder.addCase(asyncCounter.fulfilled, (state, action: PayloadAction<number>) => {
            	state.value += action.payload;
            }
        }
    });
    上記exportのasyncCounterを素子に導入して使用すると、1秒後に値が更新されたことを確認できます.
    例のasyncCounterの完了時にのみならず、pendingおよびrejectのような異なる非同期時点でも使用することができる.

    references


    https://redux-toolkit.js.org/tutorials/overview
    https://redux-toolkit.js.org/tutorials/quick-start
    https://redux-toolkit.js.org/tutorials/typescript
    https://redux-toolkit.js.org/usage/usage-with-typescript
    https://simsimjae.medium.com/next-redux-wrapper%EA%B0%80-%ED%95%84%EC%9A%94%ED%95%9C-%EC%9D%B4%EC%9C%A0-5d0176209d14
    間違ったところがあったらメッセージをお願いしますできるだけ早く修正します.
    主記録4.19