redux toolkit으로 알아보는 redux


기본 개념

  • 전역 변수 비슷한 느낌
  • redux가 해결하는 문제
    • props drilling을 통한 불필요한 rerendering과 상태 파악이 힘들다는 문제를 해결하기 위해 만들어짐
  • 구성 요소
    • 저장소 (store) = 여러 state가 객체로 저장되어 있는 느낌
    • 액션 (action) = 저장소의 값을 어떻게 변경할지 정함
    • 리듀서 (reducer) = 액션에 따라 store에 저장된 내용을 변경 (setState 느낌)

프로세스 요약

  • dispatch 훅을 통해 action을 redux store에 보내게 되면 store에서 받은 action에 알맞는 reducer를 실행해 저장된 내용을 조작한다

리듀서 작성 시 주의 사항

  • 리듀서는 순수함수로 작성 해야함, 즉 외부 내용을 변경하면 안됨 = side effect가 없어야함
  • 따라서 http 요청이나 web storage 접근 등도 불가능함

redux toolkit으로 redux 맛보기

  • 준비사항
    1. index.js에서 App 컴포넌트를 redux provider 객체로 감싸주기
    2. store.js에 redux store 만들기
    3. counter.js에 reducer와 action 작성
    4. 해당 로직을 사용할 Counter.js 컴포넌트

1.index.js에서 App 컴포넌트를 redux provider 객체로 감싸주기

//Provider와 store추가
import { Provider } from "react-redux";
import { store } from "./store";

ReactDOM.render(
  //이곳에서 아래와 같이 Provider에 store를 전달하고 App을 감싼다
  <React.StrictMode>
    <Provider store={store}> <------ provider로 감싸기
      <App />
    </Provider> <-------------------
  </React.StrictMode>,
  document.getElementById("root")
);

2. store.js에 store 만들기

import { configureStore } from "@reduxjs/toolkit";

//redux store
export const store = configureStore({   <--- 요게 store
  reducer: {},
});

3.에서 작성한 리듀서를 store에 넘겨주어야함

              ### 수정된 코드 ###

import { configureStore } from "@reduxjs/toolkit";

import counterReducer from "./redux/counter"; <--- 3번에서 작성한 리듀서

export const store = configureStore({
  reducer: {
    counter: counterReducer  <--- 리듀서 넣어주기
  },
});

3. counter.js에 reducer와 action 작성

import { createSlice } from "@reduxjs/toolkit";

const initialState = { <---- 관리할 전역 상태
  value: 0,
};

export const counterSlice = createSlice({
  name: "counter", <--- store에 전달할 name
  initialState,
  reducers: { <----- 전역 상태를 변경 할 수 있는 리듀서
    increment: (state) => { <--- 리듀서 1
      state.value += 1;
    },
    decrement: (state) => { <--- 리듀서 2
      state.value -= 1;
    },
  },
});

export const { increment, decrement } = counterSlice.actions; <---- store에 dispatch할 액션 (액션에 따라 리듀서의 동작이 달라짐)

export default counterSlice.reducer;

4. 로직을 사용할 Counter 컴포넌트

import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { decrement, increment } from '../redux/counter';

const Counter = () => {
  // useSelector 훅을 사용하면 store의 특정 값을 관찰할 수 있다
  const count = useSelector((state) => state.counter.value);

  // useDispatch 훅을 사용해 action dispatch할 준비
  const dispatch = useDispatch();

  // counter.js에서 작성한 액션을 dispatch하는 함수
  const handleIncrement = () => dispatch(increment());
  const handleDecrement = () => dispatch(decrement());

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={handleIncrement}>increment</button>
      <button onClick={handleDecrement}>decrement</button>
    </div>
  );
};

export default Counter;

😊