Redux는 React 애플리케이션의 상태를 효율적으로 관리하는 도구로, 타입스크립트와 함께 사용하면 더욱 강력한 상태 관리를 할 수 있습니다. 여기에서는 Redux와 타입스크립트를 함께 사용하여 비동기 작업을 처리하는 방법을 살펴보겠습니다.
타입스크립트와 함께 Redux 사용하기
Redux를 사용하면 상태의 변화를 예측 가능하고 일관된 방식으로 관리할 수 있습니다. 타입스크립트를 이용하면 액션 및 리듀서와 같은 Redux의 핵심 개념들을 더욱 명확하게 정의할 수 있습니다.
예를 들어, 액션과 상태의 타입을 정의할 때 다음과 같은 코드를 사용할 수 있습니다:
type Todo = {
id: number;
text: string;
completed: boolean;
};
type RootState = {
todos: Todo[];
loading: boolean;
error: string | null;
};
interface AddTodoAction {
type: 'ADD_TODO';
payload: Todo;
}
interface DeleteTodoAction {
type: 'DELETE_TODO';
payload: number;
}
type Action = AddTodoAction | DeleteTodoAction;
이러한 명확한 타입 정의는 Redux 애플리케이션의 개발을 도와주고, 에러를 사전에 방지할 수 있도록 도와줍니다.
비동기 작업 처리 방법
Redux는 기본적으로 동기적인 작업을 다루기 위한 도구이지만, 비동기 작업을 처리하기 위해 Redux Thunk, Redux Saga, 또는 Redux Observable과 같은 미들웨어를 이용할 수 있습니다. 여기에서는 Redux Thunk를 사용한 비동기 작업 처리 방법을 살펴보겠습니다.
먼저, Redux Thunk를 설치합니다:
npm install @reduxjs/toolkit redux-thunk
그리고 리듀서를 정의할 때 비동기 작업을 처리하기 위해 createAsyncThunk
를 사용합니다:
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import { RootState } from './store';
interface Post {
userId: number;
id: number;
title: string;
body: string;
}
const fetchPosts = createAsyncThunk(
'posts/fetchPosts',
async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
return (await response.json()) as Post[];
}
);
const postsSlice = createSlice({
name: 'posts',
initialState: [] as Post[],
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchPosts.fulfilled, (state, action) => {
return action.payload;
});
}
});
export const postsActions = { ...postsSlice.actions, fetchPosts };
export default postsSlice.reducer;
위 코드에서 createAsyncThunk
를 이용하여 fetchPosts
액션을 정의하고, extraReducers
를 통해 비동기 작업이 완료된 후의 상태 변화를 처리합니다.
이제 이를 컴포넌트에서 사용할 때는 useDispatch
후에 fetchPosts
액션을 디스패치하면 됩니다:
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { fetchPosts, RootState } from './store';
const PostList = () => {
const dispatch = useDispatch();
const posts = useSelector((state: RootState) => state.posts);
useEffect(() => {
dispatch(fetchPosts());
}, [dispatch]);
// ... UI 렌더링 및 상태 표시
};
이처럼 Redux와 타입스크립트를 함께 사용하여 상태를 효과적으로 관리하고, 비동기 작업을 처리할 수 있습니다. 타입스크립트의 강력함과 Redux의 효율성을 결합하여 안정적이고 확장 가능한 애플리케이션을 개발할 수 있습니다.