Redux Toolkitで非同期処理

date
Jul 9, 2022
slug
with-redux-toolkit
status
Published
summary
createAsyncThunkとrejectedの使い方
type
Post
ステータス
Redux ToolkitのcreateAsyncThunkで非同期処理を書いたことがなかったのでメモ
createAsyncThunkはRedux Toolkitにデフォルトで内蔵されています。
 
サンプル:
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';

import type { RootState } from '@/pages/_app';
import type { Playlist, AudioPlaylist } from '@/types';

type PlaylistState = {
  playlists: Playlist[];
	audioPlaylists: AudioPlaylist[];
	loadingPlaylist: boolean;
};

export const fetchPlaylists = createAsyncThunk(
  'playlists/fetchPlaylists',
  async () => {
    const response = await fetch('https://api.com/path-to-playlists.json');
    const playlists: Playlist[] = await response.json();
    return playlists;
  }
);

export const fetchAudioPlaylists = createAsyncThunk(
  'playlists/fetchAudioPlaylists',
  async () => {
    const response = await fetch('https://api.com/path-to-audio-playlists.json');
    const audioPlaylists: AudioPlaylist[] = await response.json();
    return audioPlaylists;
  }
);

const initialState: PlaylistState = {
  playlists: [],
	audioPlaylists: [],
	loadingPlaylist: false,
};

export const playlistSlice = createSlice({
  name: 'playlist',
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    // Add reducers for additional action types here, and handle loading state as needed
    builder.addCase(fetchPlaylists.fulfilled, (state, action) => {
      return {
        ...state,
        playlists: action.payload,
				loadingPlaylist: false,
      };
    });
    builder.addCase(fetchPlaylists.pending, (state, action) => {
      return {
        ...state,
        loadingPlaylist: true
      };
    });
    builder.addCase(fetchAudioPlaylists.fulfilled, (state, action) => {
      return {
        ...state,
        audioPlaylists: action.payload,
      };
    });
  },
});

export default playlistSlice.reducer;
 
rejectで値を返す場合はrejectWithValueを使います
 
	
// エラー値を返す場合は. rejectWithValue を使用する
export const fetchPlaylists = createAsyncThunk(
  'playlists/fetchPlaylists',
  async (playlists: Playlist[], { rejectWithValue }) => {

		try {
	    const response = await fetch('https://api.com/path-to-playlists.json');
	    const playlists: Playlist[] = await response.json();
	    return playlists;
	  } catch (err) {
      return rejectWithValue(err);
	  }
  }
);

...
    builder.addCase(fetchPlaylists.rejected, (state, action) => {
      return {
        ...state,
        error: action.payload,
      };
    });
...
 
設定要らなくてべんり

© わくてか 2022