Redux Toolkit의 createAsyncThunk를 사용한 비동기 처리와 미들웨어 간소화
이번 포스팅에서는 Redux Toolkit의 createAsyncThunk를 사용하여 비동기 처리를 간소화하고, 미들웨어 설정을 어떻게 개선할 수 있는지를 Before -> After 형식으로 설명하겠습니다. createAsyncThunk는 비동기 작업을 위한 간편한 방법을 제공하여 코드의 복잡성을 줄이고 유지보수를 쉽게 만듭니다.
1. 비동기 처리를 위한 미들웨어 사용의 필요성
Redux에서 비동기 작업(예: API 호출)을 처리하기 위해서는 미들웨어가 필요합니다. 기존 Redux 방식에서는 Redux Thunk나 Redux Saga와 같은 미들웨어를 설정해야 하며, 이는 코드의 복잡성을 증가시키는 원인이 됩니다. Redux Toolkit의 createAsyncThunk는 이러한 복잡한 설정을 간소화하고 코드의 가독성을 높입니다.
Before: 기존 Redux 방식의 미들웨어 설정
기존 Redux 방식에서 비동기 작업을 처리하기 위해서는 Redux Thunk를 설치하고 스토어 설정에 추가해야 했습니다.
- React 애플리케이션 생성 및 Redux 설치 먼저 React 애플리케이션을 생성하고 Redux 및 Redux Thunk를 설치합니다.
npx create-react-app my-redux-app cd my-redux-app npm install redux react-redux redux-thunk
- 복잡한 스토어 설정 Redux Thunk를 사용하기 위해 스토어에 미들웨어를 추가하는 설정을 해야 합니다.
// src/store/store.js import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; import rootReducer from '../reducers'; const store = createStore(rootReducer, applyMiddleware(thunk)); export default store;
- 액션 작성과 비동기 작업 처리 비동기 작업을 처리하기 위해 액션 크리에이터에서 Thunk 함수를 사용해야 합니다. 예를 들어, 사용자 데이터를 가져오는 액션을 작성하려면 다음과 같은 코드가 필요합니다.
// src/actions/userActions.js export const fetchUser = (userId) => { return async (dispatch) => { dispatch({ type: 'FETCH_USER_REQUEST' }); try { const response = await fetch(`/api/user/${userId}`); const data = await response.json(); dispatch({ type: 'FETCH_USER_SUCCESS', payload: data }); } catch (error) { dispatch({ type: 'FETCH_USER_FAILURE', error }); } }; };
- 리듀서 작성 리듀서는 비동기 작업의 상태(로딩, 성공, 실패)를 처리해야 합니다.
// src/reducers/userReducer.js const initialState = { user: null, loading: false, error: null, }; const userReducer = (state = initialState, action) => { switch (action.type) { case 'FETCH_USER_REQUEST': return { ...state, loading: true, }; case 'FETCH_USER_SUCCESS': return { ...state, loading: false, user: action.payload, }; case 'FETCH_USER_FAILURE': return { ...state, loading: false, error: action.error, }; default: return state; } }; export default userReducer;
After: Redux Toolkit의 createAsyncThunk 사용
Redux Toolkit의 createAsyncThunk를 사용하면 비동기 작업과 관련된 코드가 크게 간소화됩니다. 이제 Redux Toolkit을 사용하여 같은 기능을 어떻게 쉽게 구현할 수 있는지 살펴보겠습니다.
- React 애플리케이션 생성 및 Redux Toolkit 설치 Redux Toolkit을 사용할 애플리케이션을 생성하고 필요한 패키지를 설치합니다.
npx create-react-app my-redux-toolkit-app cd my-redux-toolkit-app npm install @reduxjs/toolkit react-redux
- 스토어 설정 간소화 configureStore를 사용하여 기본적으로 Redux DevTools와 미들웨어가 설정되어 있어 추가적인 설정이 필요 없습니다.
// src/app/store.js import { configureStore } from '@reduxjs/toolkit'; import userReducer from '../features/user/userSlice'; const store = configureStore({ reducer: { user: userReducer, }, }); export default store;
- createAsyncThunk를 사용한 비동기 액션 생성 createAsyncThunk를 사용하여 비동기 작업을 처리합니다. 비동기 액션을 쉽게 생성하고, 상태 관리를 자동으로 처리해줍니다.
// src/features/user/userSlice.js import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; export const fetchUser = createAsyncThunk('user/fetchUser', async (userId) => { const response = await fetch(`/api/user/${userId}`); return response.json(); }); const userSlice = createSlice({ name: 'user', initialState: { user: null, status: 'idle', error: null, }, reducers: {}, extraReducers: (builder) => { builder .addCase(fetchUser.pending, (state) => { state.status = 'loading'; }) .addCase(fetchUser.fulfilled, (state, action) => { state.status = 'succeeded'; state.user = action.payload; }) .addCase(fetchUser.rejected, (state, action) => { state.status = 'failed'; state.error = action.error.message; }); }, }); export default userSlice.reducer;
컴포넌트에서 비동기 액션 사용하기 useDispatch와 useSelector를 사용하여 컴포넌트에서 비동기 액션을 쉽게 사용할 수 있습니다.
// src/components/UserProfile.js
import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchUser } from '../features/user/userSlice';
function UserProfile({ userId }) {
const user = useSelector((state) => state.user.user);
const status = useSelector((state) => state.user.status);
const dispatch = useDispatch();
useEffect(() => {
if (status === 'idle') {
dispatch(fetchUser(userId));
}
}, [status, userId, dispatch]);
if (status === 'loading') {
return <div>Loading...</div>;
}
if (status === 'failed') {
return <div>Error loading user data.</div>;
}
return (
<div>
{user ? <h2>Welcome, {user.name}!</h2> : <p>No user data available.</p>}
</div>
);
}
export default UserProfile;
요약
- 기존 방식: Redux Thunk를 사용하여 비동기 작업을 처리할 때, 스토어 설정과 액션 작성이 복잡하고 유지보수가 어려웠습니다.
- Redux Toolkit 방식: createAsyncThunk를 사용하여 비동기 작업을 간단하게 처리하고, configureStore로 스토어 설정을 자동화하여 코드의 복잡성을 줄였습니다.
실습 코드 요약
- 기존 방식에서는 비동기 작업을 처리하기 위해 많은 코드와 복잡한 설정이 필요했습니다.
- Redux Toolkit을 사용하면 이러한 과정이 간단해지고, 비동기 작업과 관련된 코드의 양이 줄어들며 유지보수가 쉬워집니다.
'React > Redux 마스터' 카테고리의 다른 글
Redux Toolkit 기본 구조 예제: 실제 애플리케이션 생성부터 실행까지 (0) | 2024.10.24 |
---|---|
리덕스의 기본 컴포넌트 개념과 사용 방법 (0) | 2024.10.24 |
Redux Toolkit 활용 실습(3): React와 Redux의 호환성 개선 (0) | 2024.10.24 |
Redux Toolkit 활용 실습(2): 성능 개선 (0) | 2024.10.24 |
Redux Toolkit 활용 실습(1): 초기 설정 (0) | 2024.10.24 |