..

Search

37) Redux 활용하기

Redux 활용하기


Counter에 기능 추가하기

이번 장에서는 앞서 살펴 본 Counter 예제에 기능들을 추가하면서 Redux를 활용하는 방법에 대해 좀 더 자세히 살펴보도록 하겠습니다.


증감하는 수량 설정하기

앞선 Counter 예제에서는 증가와 감소 버튼을 누를 때마다 Count 값이 1씩 증가하거나 감소하였습니다. 이번에는 Redux를 활용하여 사용자가 증감하는 수량을 직접 설정할 수 있도록 구현해 봅시다.

 

우선 counterSlice 컴포넌트에 증감하는 수량을 설정하기 위한 Reducer 함수인 incrementByQuantity()를 정의합니다. 이때 사용되는 Action 객체의 payload 필드에는 Action의 타입에 따라 실행에 필요한 추가적인 state값을 저장할 수 있습니다.

counterSlice.js
export const counterSlice = createSlice({
  // ...
  reducers: {
    // ...
    incrementByQuantity: (state, action) => {
      state.value += action.payload;
    }
  }
});

export const {
  increment,
  decrement,
  incrementByQuantity
} = counterSlice.actions;

export const selectCount = (state) => state.counter.value;

export default counterSlice.reducer;
예제(App.js)
import { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import {
  decrement,
  increment,
  incrementByQuantity,
  selectCount
} from "./counterSlice";

const App = () => {
  const count = useSelector(selectCount);
  const dispatch = useDispatch();
  const [incrementQuantity, setIncrementQuantity] = useState("2");

  return (
    <div>
      <div>
        // ...
      </div>
      <div>
        <input
          value={incrementQuantity}
          onChange={(e) => setIncrementQuantity(e.target.value)}
        />
        <button
          onClick={() =>
            dispatch(incrementByQuantity(Number(incrementQuantity)))
          }
        >
          씩 증가
        </button>
      </div>
    </div>
  );
};

export default App;


비동기적으로 증감시키기

이번에는 Count 값을 증가시키는 버튼을 눌렀을 때 1초 간의 딜레이 후 동작하도록 기능을 추가해 보도록 하겠습니다.

 

우선 counterSlice 컴포넌트에 아래 코드를 추가합니다. 아래 함수는 보통 thunk라고 불리며, 비동기 로직을 수행할 수 있도록 해 주는 코드입니다. 이 함수는 일반 Action처럼 Dispatch 될 수 있습니다. 이제 Dispatch 함수의 첫 번째 인수로 thunk가 호출되며, 이후 비동기 코드가 실행되고 다른 Action들이 Dispatch 될 것입니다.

counterSlice.js
// ...
export const incrementAsync = (quantity) => (dispatch) => {
  setTimeout(() => {
    dispatch(incrementByQuantity(quantity));
  }, 1000);
};
// ...
예제(App.js)
import { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import {
  decrement,
  increment,
  incrementByQuantity,
  incrementAsync,
  selectCount
} from "./counterSlice";

const App = () => {
  // ...
  return (
    <div>
      <div>
        // ...
      </div>
      <div>
        // ...
        <button
          onClick={() =>
            dispatch(incrementAsync(Number(incrementQuantity) || 0))
          }
        >
          씩 증가(비동기)
        </button>
      </div>
    </div>
  );
};

export default App;


연습문제