redux에서 thunk는 '지연된 작업을 수행하는 코드 조각'이라는 의미가 있다.
코드에서 특정 작업을 일정시간 동안 지연시키고 실행하는 부분을 의미하는데 보통 이런 지연된 작업은 비동기작업을 다룰 때 주로 사용한다.
redux thunk는 미들웨어 중 하나로 비동기 작업을 처리하기 위해 사용한다.
일반적으로 redux는 동기적인 작업을 수행하는 데 초점이 맞춰진 상태관리 라이브러리이다. 참고 - 동기와 비동기의 개념
하지만 실제로는 API호출, 데이터 가져오기 등의 비동기 작업이 필요할 때가 많다.
그래서 Redux 액션 생성자에서 비동기 작업을 처리할 수 있도록 도와주는 미들웨어인 redux Thunk를 사용하여 비동기 작업을 처리하고 액션을 디스패치하여 상태를 업데이트 하게 만들어준다.
redux toolkit에서 Async thunk를 이용하면 비동기 작업을 간편하게 처리할 수 있는데
Async Thunk는 createAsyncThunk함수를 사용하여 생성한다.
createAsyncThunk 함수는 액션 생성자 함수를 생성하고, 비동기 작업의 성공, 실패, 진행 상태에 따라 액션을 자동으로 디스패치하는 Thunk 액션 생성자 함수를 반환한다.
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와 같이 쓴다.