redux-toolkit : createSlice, createAsyncThunk

윤동훈·2023년 7월 13일
0

[Redux toolkit]

  • 설정
  • 미들웨어 설치
  • 반복되는 코드
  • 불변성 유지
    ==> 이런 불편한 것들을 해소
$ npm install @reduxjs/toolkit

createSlice

  • reducer 함수의 객체, 슬라이스 이름, 초기 상태 값을 받아들여서 해당 액션 생성자와 액션 유형으로 slice reducer를 자동으로 생성함

  • createSlice()는 다음과 같은 파라미터로 구성되어 있다.
    - name : 해당 모듈의 이름을 작성

    • initialState : 해당 모듈의 초기값을 세팅한다.
    • reducer : 리듀서를 작성한다. 이때 해당 리듀서의 키값으로 액션 함수가 자동으로 생성
export const postsSlice = createSlice({
  name: 'posts', // 이름
  initialState, // 초기값
  reducers: { // posts.actions
    setPosts: (state, { payload }) => { // action.payload
      state.selPosts = payload;
    },
  },
  // extraReducers는 createSlice가 생성한 액션 타입 외 다른 액션 타입에 응답할 수 있도록 합니다.
  // 아래처럼 슬라이스 외부에서 액션 타입을 참조하여 상태를 변화시킬 수 있습니다.
  extraReducers: (builder) => {
    builder
      .addCase(getAllPosts.fulfilled, (state, { payload }) => {
        state.allPosts = payload; // fulfilled 성공
      })
      .addCase(getAllPosts.rejected, (state, { payload }) => {
        console.log('rejected', payload); // rejected 실패
      });
  },
});

export const { setPosts } = postsSlice.actions;
// actions 는 내보내줘야 함(외부 컴포넌트에서 접근 가능하도록)
export default postsSlice.reducer;
  • createSlice에서는 state값을 mutate하는 것이 가능
  1. 원본에 추가,삭제,수정 등 mutate 하는 방식
  2. 이전과 같은 방식으로 새로운 배열 혹은 객체로 대체하는 방식

createAsyncThunk

  • 액션 타입 문자열, 프로미스를 반환하는 비동기 함수, 추가 옵션 순서대로 인자를 받는 함수다.
    입력받은 액션 타입 문자열을 기반으로 프로미스 라이프사이클 액션 타입을 생성하고, thunk action creator를 반환한다.

  • thunk action creator: 프로미스 콜백을 실행하고 프로미스를 기반으로 라이프사이클 액션을 디스패치한다.

  • 리듀서를 생성해주는 기능은 없기 때문에 액션들을 처리할 로직을 직접 작성해야 한다.

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
import { userAPI } from './userAPI'

const fetchUserById = createAsyncThunk(
  // string action type value: 이 값에 따라 pending, fulfilled, rejected가 붙은 액션 타입이 생성된다.
  'users/fetchByIdStatus',
  // payloadCreator callback: 비동기 로직의 결과를 포함하고 있는 프로미스를 반환하는 비동기 함수
  async (userId, thunkAPI) => {
    const response = await userAPI.fetchById(userId);
    return response.data;
  },
  // 세 번째 파라미터로 추가 옵션을 설정할 수 있다.
  // condition(arg, { getState, extra } ): boolean (비동기 로직 실행 전에 취소하거나, 실행 도중에 취소할 수 있다.)
  // dispatchConditionRejection: boolean (true면, condition()이 false를 반환할 때 액션 자체를 디스패치하지 않도록 한다.)
  // idGenerator(): string (requestId를 만들어준다. 같은 requestId일 경우 요청하지 않는 등의 기능을 사용할 수 있게 된다.)
);

createAsyncThunk는 thunk action creator를 반환한다.
위의 경우를 예로 들면, 다음 세 가지 thunk action creator가 반환된다.
fetchUserById.pending: 'users/fetchByIdStatus/pending' 액션을 디스패치하는 thunk action creator
fetchUserById.fulfilled: 'users/fetchByIdStatus/fulfilled' 액션을 디스패치하는 thunk action creator
fetchUserById.rejected: 'users/fetchByIdStatus/rejected' 액션을 디스패치하는 thunk action creator
이 액션들이 디스패치되면, thunk는 아래 과정을 실행한다.
pending 액션을 디스패치한다.
payloadCreator 콜백을 호출하고 프로미스가 반환되기를 기다린다.
프로미스가 반환되면, 프로미스의 상태에 따라 다음 행동을 실행한다.
프로미스가 이행된 상태라면, action.payload를 fulfilled 액션에 담아 디스패치한다.
프로미스가 거부된 상태라면, rejected 액션을 디스패치하되 rejectedValue(value) 함수의 반환값에 따라 액션에 어떤 값이 넘어올지 결정된다.
rejectedValue가 값을 반환하면, action.payload를 reject 액션에 담는다.
rejectedValue가 없거나 값을 반환하지 않았다면, action.error 값처럼 오류의 직렬화된 버전을 reject 액션에 담는다.
디스패치된 액션이 어떤 액션인지에 상관없이, 항상 최종적으로 디스패치된 액션을 담고 있는 이행된 프로미스를 반환한다.

0개의 댓글