Redux Toolkit

jeongjwon·2023년 5월 23일
0

이번 솔로 프로젝트를 진행하면서 북마크에 대한 데이터를 처리하는데 있어서 애를 먹었다. 전체적인 데이터는 API를 통해 상태를 저장하고 북마크를 클릭하면 로컬 스토리지에 북마크된 id 를 추가시켜주고, 재클릭시 해당 데이터의 id 를 삭제시켜줌으로써 전역으로 관리해야하는 필요성을 느꼈다. 배웠던 redux 를 활용해보고자 했는데 뭔가 어렵게 느껴졌고, redux 를 쉽게 사용할 수 있는 Redux Toolkit 이라는 라이브러리를 알게 되어서 이를 블로깅 해 보고자 한다.

먼저, Redux의 간단한 이론은 알지만 한 번 더 짚고 넘어가야할 것 같다.


Redux

React 는 단방향 데이터 흐름이기 때문에 상태를 사용하기 위해서는 최상위 컴포넌트에서 사용하고자 하는 컴포넌트로 props drilling 을 해야 했었다. 소량의 데이터라면 전달해야하는 props 정도는 괜찮지만, 대량의 데이터라면 관리하기도 어려워지고 중간에 에러가 발생시 에러 발생 시점을 발견하기도 쉽지 않다. 그렇기 때문에 상태를 전역 관리의 필요성이 느껴졌고 이 방법이 바로 Redux 이다.

리덕스를 사용하는 구조는 위와 같다.

  1. 전역 상태를 전부 하나의 저장소 (Store) 안에 있는 객체 트리에 저장한다.
  2. 상태를 변경하고자 하면 변경될 상태에 대한 정보가 담긴 Action 객체가 생성된다.
  3. 그 Action 객체는 Dispatch 를 통해 Reducer 함수로 전달한다.
  4. Reducer 는 변화를 일으키는 함수로써 전달받은 Action 객체를 이용해 새로운 상태를 만들어서 Store 에 전달한다.

즉, Action -> Dispatch -> Reducer -> Store 순으로 데이터가 단방향으로 흐른다.


4가지 개념만 알면 쉽게 느껴진다. 하지만

  • Redux Store 설정은 복잡하다.
  • Redux 를 유용하게 사용하려면 많은 패키지를 설치해야 한다.
  • Redux 는 보일러플레이트, 어떤 일을 하기 위해 꼭 작성해야 하는 상용구 코드를 너무 많이 요구한다.

라는 몇 가지 이유 때문에 Redux 를 더 쉽게 사용할 수 있는 툴킷이 등장한다. 이것이 바로 Redux Toolkit 이다.



Redux 실습

//store.js
import { createStore } from "redux";
import reducer from './reducer';
const initialValue = { value: 0 };
const store = createStore(reducer, initialValue);


//reducer.js
function reducer(state, action) {
  if (action.type === "PLUS") {
    // 반환값은 react의 불변성 때문에 기존의 state 를 복제해서 값을 바꿔줌
    return { ...state, value: state.value + action.step };
  }
  return state;
}


// Counter.js
import { useSelector, useDispatch } from "react-redux";
function Counter() {
  const dispatch = useDispatch();
  const count = useSelector((state) => state.value);
  return (
    <div>
      <button onClick={() => dispatch({ type: "PLUS", step: 2 })}> +</button>
      {count}
    </div>
  );
}


// App.js
import { Provider } from "react-redux";
import Counter from "./Counter";

export default function App() {
  return (
    <Provider store={store}>
      <div>
        <Counter />
      </div>
    </Provider>
  );
}


Redux Toolkit

Store 연동하기

기존 리덕스와 마찬가지로 Provider 컴포넌트를 이용해 react-redux에서 리액트 앱에 스토어를 연동할 수 있게 해준다. 연동할 컴포넌트를 감싸주고 props 로 사용할 스토어를 지정해준다.

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { Provider } from "react-redux";
import store from "./store/store.js";

ReactDOM.createRoot(document.getElementById('root')).render(
    <Provider store={store}>
      <App />
    </Provider>
)

스토어 구성

configureStore() 는 기존 리덕스의 createStore 를 추상화한 것으로, 기존의 번거로운 설정 과정을 자동화 역할을 하는 스토어를 만들어준다.

//store.js
import { configureStore } from "@reduxjs/toolkit";

export const store = configureStore({
	reducer: counterSlice,
});

createSlice 생성

기존 리덕스에서 Action 객체를 Dispatch 하기위해 별도의 함수를 작성하고, Reducer를 통해 새로운 Action 객체를 리턴해야 했었다.
createSlice() 는 Action 객체에 대한 함수 설정이나 Reducer 를 따로 생성하지 않아도 된다.

//counterSlice.js
import { craeteSlice } from "@reduxjs/toolkit";

const counterSlice = createSlice({
	name: "counter",
  	initialState: { value: 0 },
    reducers: {
    	up: (state, action) => {
          state.value += action.payload;
        },
    }
})
export const couterActions = counterSlice.actions;
export default counterActions.reducer;
  • initialState 를 통해 state의 초기상태를 정의한다.
  • reducers 에서 Action 을 생성한다.
  • 생성된 action 인 up / counterActions 를 사용할 컴포넌트에 import 한다.
  • 하나의 저장소인 store.js 에 slice.reducer 로 전달한다.

useSelector, useDispatch 로 상태 접근하기

//Counter.js
import { useSelector, useDispatch } from "react-redux";
import CouterActions from "./counterSlice.js";

function Counter() {
	const dispatch = useDispatch();
  	const count = useSelecotr(state => state.counter.value);
  	return(
    	<div>
      		<button onClick={() => dispatch({type: 'up' , step: 2})}>+</button>
    )
}
  • useSelector() 로 스토어에서 상태값을 가져온다. 기존 리덕스에서는 state.value 였다면 생성된 createSlice 의 name 값(counter)을 이용하여 state.counter.value 를 불러온다.
  • useDispatch() 를 통해 변경되는 값을 스토어로 전달한다.

Reference

https://blog.hwahae.co.kr/all/tech/6946

https://velog.io/@sweet_pumpkin/%EB%AC%B4%EC%9E%91%EC%A0%95%EB%94%B0%EB%9D%BC%ED%95%98%EA%B8%B0-%EC%B5%9C%EA%B3%A0-%EB%A6%AC%EB%8D%95%EC%8A%A4%EC%95%BC-%EA%B3%A0%EB%A7%99%EB%8B%A4-Redux-Redux-Toolkit-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0

0개의 댓글