
- Redux Thunk는 Redux에서 비동기 작업을 처리하는 미들웨어이다.
- 기본 Redux 액션은 순수한 동기 액션 객체여야 한다,
- 하지만 Redux Thunk를 사용하면 액션을 함수로 반환할 수 있어서,
- 비동기 작업(API 호출 등)을 수행할 수 있다.
우선 들어가기 전에 Redux, React, Thunk의 상관관계에 대해서 정리하고 들어가자.
정의
React는 UI 라이브러리로, 컴포넌트 기반으로 화면을 구성하고 상태 관리 할 수 있다.
Redux는 React에서 상태 관리를 위한 상태관리 라이브러리이다.(리액트 없이도 사용 가능하다)
Redux-Thunk는 Redux에서 비동기 작업을 처리할 때 가장 기본적으로 사용하는 미들웨어이다.
상관 관계
React의 상태 관리 기능은 컴포넌트 단위로 제한되기 때문에, 전역 상태를 관리하기 위해 별도의 라이브러리인 Redux를 사용한다. Redux를 사용하면 여러 컴포넌트 간 상태를 일관되게 공유할 수 있다.
실무 작업에서는 API 호출 같은 비동기 작업이 많이 필요하다, Redux는 동기 액션을 처리하기 때문에 비동기 작업을 처리할 수 있는 Redux-Thunk를 활용한다.
Redux Thunk의 동작 로직
React에서 Redux Thunk를 사용하면, React 컴포넌트는 전역 상태를 관리하는 Redux 스토어와 상호작용할 수 있고, 비동기 로직을 Redux Thunk를 통해 처리할 수 있다.
React 컴포넌트는 Redux의 dispatch 함수를 사용해 Thunk를 호출하여 비동기 액션을 트리거하고, 비동기 작업의 결과에 따라 상태가 업데이트되면 컴포넌트는 리렌더링된다.
npm install redux-thunk
아래에 작성된 코드는 그냥 이해를 돕기 위한 예시이다.
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
const store = createStore(rootReducer, applyMiddleware(thunk));
//이 함수는 dispatch와 getState를 인자로 받으며, 여기서 비동기 작업을 실행할 수 있다.
//여기서 fetchUserData는 비동기 API 호출을 처리하고, 결과에 따라 성공 또는 실패 액션을 dispatch로 처리한다.
const fetchUserData = () => {
return async (dispatch) => {
dispatch({ type: 'FETCH_USER_REQUEST' });
try {
const response = await fetch('https://api.example.com/user');
const data = await response.json();
dispatch({ type: 'FETCH_USER_SUCCESS', payload: data });
} catch (error) {
dispatch({ type: 'FETCH_USER_FAILURE', error });
}
};
};
const userReducer = (state = {}, action) => {
switch (action.type) {
case 'FETCH_USER_REQUEST':
return { ...state, loading: true };
case 'FETCH_USER_SUCCESS':
return { ...state, loading: false, data: action.payload };
case 'FETCH_USER_FAILURE':
return { ...state, loading: false, error: action.error };
default:
return state;
}
};
import { useDispatch, useSelector } from 'react-redux';
import { useEffect } from 'react';
import { fetchUserData } from './actions';
const UserProfile = () => {
const dispatch = useDispatch();
const user = useSelector((state) => state.user);
useEffect(() => {
dispatch(fetchUserData()); // 비동기 액션을 호출
}, [dispatch]);
if (user.loading) {
return <div>Loading...</div>;
}
if (user.error) {
return <div>Error: {user.error}</div>;
}
return (
<div>
<h1>{user.data.name}</h1>
<p>{user.data.email}</p>
</div>
);
};
export default UserProfile;
