리덕스 툴킷은 기존의 리덕스를 사용할 때 작성하던 코드를 더 간결하게 작성할 수 있도록 해줍니다. 또한 내부적으로 Immer를 사용하여 자동으로 상태의 불변성을 유지할 수 있으며, 이로 인해 리듀서 함수를 더 간결하게 작성할 수 있습니다. 그뿐만 아니라 기존 리덕스에서 리듀서를 하나로 통합하고, 통합한 리듀서를 스토어에 연결하기 위해 스토어를 생성하는 번거로운 과정을 리덕스 툴킷에서는 한 번에 처리할 수 있습니다.

이번에는 2장에서 리덕스를 활용해 만든 계산기와 투두리스트 프로젝트를 리덕스 툴킷을 활용하여 구현해 보겠습니다. 코드를 작성하기 전에 리덕스 툴킷을 사용하기 위한 설치 및 환경 설정을 진행하겠습니다.

3.2.1 Redux Toolkit 사용 환경 세팅하기

리액트 프로젝트 생성 후 프로젝트 디렉토리에 리덕스 툴킷에 필요한 라이브러리 및 의존성을 설치해 줍니다.

npm install react-redux 
npm install @reduxjs/toolkit

설치가 제대로 되었다면 package.json 파일에 ‘@reduxjs/toolkit’과 ‘react-redux’가 추가 되었음을 확인할 수 있습니다.

// package.json

"dependencies": {
    "@reduxjs/toolkit": "^1.9.7",
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "eslint-plugin-jsx-a11y": "^6.7.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-redux": "^8.1.3",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },

3.2.2 Components 생성

기능 없이 계산기와 투두리스트의 틀만 잡아주는 컴포넌트를 생성하고 App.js에서 렌더링을 해줍니다.

1) Calculator 컴포넌트 만들기

// components/Calculator.jsx

import { useState } from "react";

export default function Calculator() {
    const [inputValue, setInputValue] = useState("");
    return (
        <>
            <div>결과: </div>
            <input
                type="number"
                value={inputValue}
                onChange={(e) => setInputValue(e.target.value)}
            />
            <div>
                <button onClick={() => {}}>+</button>
                <button onClick={() => {}}>-</button>
                <button onClick={() => {}}>/</button>
                <button onClick={() => {}}>*</button>
                <button onClick={() => {}}>C</button>
            </div>
		<br />
        </>
    );
}

2) TodoList 컴포넌트 만들기

// components/TodoList.jsx

import { useState } from "react";

export default function TodoList() {
    const [inputValue, setInputValue] = useState("");
    const todos = [];
    return (
        <>
            <form onSubmit={(e) => e.preventDefault()}>
                <input
                    type="text"
                    value={inputValue}
                    placeholder="할 일을 작성해 주세요"
                    onChange={(e) => setInputValue(e.target.value)}
                />
                <button type="submit" onClick={() => {}}>
                    추가
                </button>
            </form>
            {todos.map((todo) => (
                <section key={todo.id}>
                    <input type="checkbox" onClick={() => {}} />
                    <div
                        style={{
                            textDecoration: todo.isDone
                                ? "line-through"
                                : "none",
                        }}
                    >
                        {todo.content}
                    </div>
                    <button onClick={() => {}}>❌</button>
                </section>
            ))}
        </>
    );
}