Redux는 React 애플리케이션에서 상태를 효과적으로 관리하기 위한 도구로, 상태의 예측 가능성과 변이를 추적하는 데 도움을 줍니다. 타입스크립트(TypeScript)는 JavaScript에 정적 타입을 추가한 언어로, 코드의 안정성과 가독성을 높일 수 있습니다. 이 블로그에서는 Redux와 타입스크립트를 함께 사용하여 React 애플리케이션의 상태 관리를 어떻게 향상시킬 수 있는지에 대해 살펴보겠습니다.
1. Redux와 타입스크립트 설치
먼저, 프로젝트에 Redux와 타입스크립트를 설치해야 합니다. 다음 명령어를 사용하여 패키지를 설치합니다.
npm install redux react-redux @types/react-redux
2. 리덕스 액션 타입 정의
Redux에서 사용할 액션 타입을 정의할 때, 타입스크립트를 활용하여 정적 타입을 지정할 수 있습니다. 예를 들어, 다음과 같이 액션 타입을 정의할 수 있습니다.
// actions.ts
export const ADD_TODO = 'ADD_TODO';
export const TOGGLE_TODO = 'TOGGLE_TODO';
export interface AddTodoAction {
type: typeof ADD_TODO;
payload: {
id: number;
text: string;
};
}
export interface ToggleTodoAction {
type: typeof TOGGLE_TODO;
payload: {
id: number;
};
}
export type TodoAction = AddTodoAction | ToggleTodoAction;
위 예시에서 AddTodoAction
과 ToggleTodoAction
은 각각 ADD_TODO
와 TOGGLE_TODO
라는 문자열 타입의 type
프로퍼티와 payload
프로퍼티를 가진 객체로 정의되어 있습니다. 또한, TodoAction
은 이 두 타입 중 하나를 가질 수 있는 유니온 타입으로 정의되어 있습니다.
3. 리덕스 상태 관리
Redux에서 상태와 액션을 관리할 때, 타입스크립트를 사용하여 상태의 타입과 함께 reducer와 action creator 함수의 반환 타입을 명시할 수 있습니다. 예를 들어, 다음과 같이 상태와 reducer를 정의할 수 있습니다.
// types.ts
export interface Todo {
id: number;
text: string;
completed: boolean;
}
export interface TodoState {
todos: Todo[];
}
// reducer.ts
import { TodoAction } from './actions';
import { TodoState } from './types';
const initialState: TodoState = {
todos: []
};
const todoReducer = (state = initialState, action: TodoAction): TodoState => {
switch (action.type) {
case 'ADD_TODO':
return {
todos: [
...state.todos,
{
id: action.payload.id,
text: action.payload.text,
completed: false
}
]
};
case 'TOGGLE_TODO':
return {
todos: state.todos.map(todo =>
todo.id === action.payload.id
? { ...todo, completed: !todo.completed }
: todo
)
};
default:
return state;
}
};
export default todoReducer;
위 코드에서 Todo
와 TodoState
는 각각 할 일 항목과 할 일 상태의 타입을 정의하고, todoReducer
에서는 해당 타입을 이용하여 상태와 액션을 관리합니다.
4. 리액트 컴포넌트와 연동
마지막으로, 리덕스 상태를 리액트 컴포넌트와 연동할 때, react-redux
라이브러리를 사용하고 타입스크립트를 활용하여 상태와 디스패치를 전달할 수 있습니다. 예를 들어, 다음과 같이 컴포넌트를 작성할 수 있습니다.
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { RootState } from '../store';
import { Todo, TodoState } from '../store/types';
import { addTodo, toggleTodo } from '../store/actions';
const TodoList: React.FC = () => {
const todos = useSelector<RootState, Todo[]>(state => state.todo.todos);
const dispatch = useDispatch();
const handleAddTodo = (text: string) => {
const id = todos.length + 1;
dispatch(addTodo({ id, text }));
};
const handleToggleTodo = (id: number) => {
dispatch(toggleTodo({ id }));
};
return (
<div>
{todos.map(todo => (
<div key={todo.id}>
<span
style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}
onClick={() => handleToggleTodo(todo.id)}
>
{todo.text}
</span>
</div>
))}
<input type="text" onKeyDown={(e) => {
if (e.key === 'Enter') {
handleAddTodo(e.currentTarget.value);
e.currentTarget.value = '';
}
}} />
</div>
);
};
export default TodoList;
위 코드에서 useSelector
를 사용하여 상태를 가져오고, useDispatch
를 사용하여 디스패치를 가져온 후, 해당 상태와 디스패치를 이용하여 상태를 업데이트하고 관리할 수 있습니다.
이러한 방법으로 Redux와 타입스크립트를 함께 사용하여, React 애플리케이션의 상태를 보다 안정적으로 관리할 수 있습니다.
이상으로 Redux와 타입스크립트를 함께 사용하여 상태를 관리하는 방법에 대해 알아보았습니다. 향후 프로젝트 개발 시에 유용하게 활용할 수 있도록 공부하시기 바랍니다.
태그: Redux, TypeScript, React, 상태 관리, 연동 방법