redux toolkit 비동기 작업을 도와주는 redux thunk

완두콩·2023년 6월 19일
0

redux/toolkit

목록 보기
6/8


redux에서 thunk는 '지연된 작업을 수행하는 코드 조각'이라는 의미가 있다.
코드에서 특정 작업을 일정시간 동안 지연시키고 실행하는 부분을 의미하는데 보통 이런 지연된 작업은 비동기작업을 다룰 때 주로 사용한다.

redux thunk는 미들웨어 중 하나로 비동기 작업을 처리하기 위해 사용한다.
일반적으로 redux는 동기적인 작업을 수행하는 데 초점이 맞춰진 상태관리 라이브러리이다. 참고 - 동기와 비동기의 개념
하지만 실제로는 API호출, 데이터 가져오기 등의 비동기 작업이 필요할 때가 많다.
그래서 Redux 액션 생성자에서 비동기 작업을 처리할 수 있도록 도와주는 미들웨어인 redux Thunk를 사용하여 비동기 작업을 처리하고 액션을 디스패치하여 상태를 업데이트 하게 만들어준다.

redux toolkit에서 Async thunk를 이용하면 비동기 작업을 간편하게 처리할 수 있는데
Async Thunk는 createAsyncThunk함수를 사용하여 생성한다.

createAsyncThunk 함수는 액션 생성자 함수를 생성하고, 비동기 작업의 성공, 실패, 진행 상태에 따라 액션을 자동으로 디스패치하는 Thunk 액션 생성자 함수를 반환한다.

async Thunk의 기본적 절차

  1. createAsyncThunk함수를 사용하여 Thunk 액션 생성자 함수를 생성한다.
  2. 비동기 작업을 수행하는 콜백함수 정의
  3. 비동기 작업이 시작되면 Thunk액션생성자 함수 호출
  4. thunk액션 생성자 함수내에서 비동기 작업을 수행. 작업 진행 상황에 따라 pending, fulfilled, rejected 상태에 해당하는 액션 자동 디스패치.

Async Thunk 를 사용하면 액션 생성과 디스패치, 상태갱신을 한 곳에서 관리 할 수 있다.

코드

import { createSlice, nanoid, createAsyncThunk } from "@reduxjs/toolkit";

const POSTS_URL = 'https://jsonplaceholder.typicode.com/posts';

const initialState = {
  posts: [],
  state: 'idle', // idle | loading | succeded | failed
  error: null
}
// 비동기 작업을 수행하는 Thunk 액션 생성자 함수
export const fetchPosts = createAsyncThunk(
'posts/fetchPosts',//액션 타입
async () => {
  try {
    const response = await axios.get(POSTS_URL); // 비동기 작업을 수행하는 API 호출
    console.log('fetchPosts', response);
    return [...response.data]; // 비동기 작업 결과를 반환
  } catch (err) {
    return err.message;
  }
})


// 비동기 작업을 처리하는 Reducer
const postsSlice = createSlice({
  name: 'posts',
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    builder
       .addCase(fetchPosts.pending, (state) => {
        state.status = 'loading'; // 작업이 진행 중임을 표시
      })
       .addCase(fetchPosts.fulfilled, (state, action) => {
        state.status = 'succeeded'; // 작업이 성공적으로 완료됨을 표시

        //날짜와 리액션 추가
        let min = 1;
        const loadedPosts = action.payload.map(post => {
          post.data = sub(new Date(), { minutes: min++ }).toISOString()

          post.reactions = {
            thumbsUp: 0,
            wow: 0,
            heart: 0,
            rocket: 0,
            coffee: 0
          }

          return post;
        });

        //게시물들을 배열에 추가한다.
        state.posts = state.posts.concat(loadedPosts)

      })
     .addCase(fetchPosts.rejected, (state, action) => {
        state.status = 'failed' // 작업이 실패함을 표시
        state.error = action.error.message // 에러 메시지를 상태에 저장
      })
  },
});

asyncthunk는 extraReducers와 같이 쓴다.

profile
공부하자. 기록하자. 쫌!

0개의 댓글