🙆

自分用メモ useReducer × useContextの使い方

2023/01/14に公開

参考記事

https://zenn.dev/sorye/articles/usereducer-and-usecontext-in-typescript

使い方

    1. stateactionを定義する
reducer.ts
type State = {
  CountState: number;
  ChangeValue: number;
};

type Action =
  | {
      type: "countUp";
    }
  | {
      type: "countDown";
    }
  | {
      type: "changeValue";
      payload: { value: number };
    };
    1. reducerを定義する

state に対しての操作を行う。
戻り値の型を必ずつける。

reducer.ts
const reducer = (state: State, action: Action): State => {
  switch (action.type) {
    case "countUp":
      return { ...state, CountState: state.CountState + state.ChangeValue };
    case "countDown":
      return { ...state, CountState: state.CountState - state.ChangeValue };
    case "changeValue":
      return { ...state, ChangeValue: action.payload.value };
  }
};
    1. カスタムフックを作成する
reducer.ts
export default function useCountReducer() {
  const [countState, dispatchCountState] = useReducer(reducer, initial);

  return { countState, dispatchCountState };
}
    1. initialを定義する

戻り値は、Stateを与える
vsCode の予測変換から不足しているプロパティを呼びだすと楽

reducer.ts
const initial: State = {
  CountState: 0,
  ChangeValue: 1,
};
    1. useContext で使用する初期値を作成する
      vsCode の予測変換から不足しているプロパティを呼びだすと楽
reducer.ts
export const defaultCountReducerContext: ReturnType<typeof useCountReducer> = {
  countState: {
    CountState: 0,
    ChangeValue: 1,
  },
  dispatchCountState: () => {},
};
    1. provider に移動して、createContext を作成する
provider.tsx
export const CountReducerContext = createContext(defaultCountReducerContext);
    1. useReducerを使用する為のコンポーネントを作成する
provider.tsx
type TCountReducerContext = {
  children: JSX.Element | JSX.Element[];
};

export default function CountReducerProvider(props: TCountReducerContext) {
  return (
    <CountReducerContext.Provider value={useCountReducer()}>
      {props.children}
    </CountReducerContext.Provider>
  );
}
  • 8 pages 配下で、使用する場所に適用
page.tsx
export default function Page() {
  return (
    <div>
      <CountReducerProvider>
        <CountPage />
      </CountReducerProvider>
    </div>
  );
}

終わり。
使用したい箇所で、useContextから呼び出せば OK

const { countState, dispatchCountState } = useContext(CountReducerContext);

Discussion