0
0

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.

【TypeScript + React Hooks】useReducerでactionの型定義をtypeの値によって変更する

Last updated at Posted at 2021-01-14

はじめに

TypeScript + React HooksのuseReducerで、オブジェクトの配列のstateを作成したとき、
dispatch関数がtypeの値に応じて必要な引数だけを要求するようにしたくなった

つまり、reducerの引数であるactionが、
typeの値に対応したpayloadを持つように型定義したい

方法

型定義において、typeをtype: string;ではなく具体値で定義する

interface AddAction {
  type: 'add',
  payload: {
    id: number;
    a: number;
    b: string;
  }
}
interface RemoveAction {
  type: 'remove',
  payload: {
    id: number;
  }
}

定義したそれぞれの型を | でつなぐ

const reducer = (
  state: Array<MyDataType>,
  action: AddAction | RemoveAction,
) => {
  if (action.type === 'add') {
    // addの処理
  } else if (action.type === 'remove') {
    // removeの処理
  }
}

実装例

  • オブジェクトの配列であるstateについての実装例
  • users:ユーザ情報(id, name, age)を管理するオブジェクトの配列のstate
  • 新たにユーザ情報を追加するaddと、idをもとにageを更新するupdateAgeを実装
sample.tsx
import React, { useReducer } from 'react';

interface User {
  id: number;
  name: string;
  age: number;
  gender: string;
}

interface AddAction {
  type: 'add';
  payload: User;
}

interface UpdateAgeAction {
  type: 'updateAge';
  payload: {
    id: number;
    age: number;
  };
}

export const reducer = (
  state: Array<User>, 
  action: AddAction | UpdateAgeAction
): Array<User> => {
  if (action.type === 'add') {
    // addの処理
  } else if (action.type === 'updateAge') {
    // ageの更新処理
  }
}


const MyComponent: React.FC = () => {
  const [users, usersDispatch] = useReducer(reducer, []);

  const addUser = (newUser: User) => {
    usersDispatch({
      type: 'add',
      payload: newUser,
    }
  }
  const updateAge = (userId: number, newAge: number) => {
    usersDispatch({
      type: 'updateAge',
      payload: {
        id: userId,
        age: newAge,
      }
    }
  }
  // 以下省略
}
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?