REDUX 입문 - 3. Toolkit으로 구현한 Counter 예제

김명성·2022년 6월 13일
0
import { createSlice, configureStore} from "@reduxjs/toolkit";

const initialState = { counter : 0, showCounter: true };

// toolkit은 기존 상태를 바꿀 수 없게
// immer라는 패키지를 자동 적용하여 상태를 복제해주기 때문에
// 메서드 내부에서 state.counter++처럼 직접 조작할 수 있게 해준다.
const counterSlice = createSlice(
  {
    // toolkit의 3가지 인수
    // name은 reducer의 이름.
    // initialState는 초기값 지정.
    // reducers는 state를 조작할 수 있게 하는 dispatcher 메서드이다.
    name: 'counter',
    initialState,
    reducers: {
      increment(state){
        state.counter++;
      },
      decrement(state){
        state.counter--;
      },
      //payload는 정해진 메서드이다. 이름을 바꿀 수 없다.
      increase(state, action){
        state.counter = state.counter + action.payload;
      },
      toggoleCounter(state){
        state.showCounter = !state.showCounter
      }
    }
  }
);

// toolkit에서는 createStore가 아닌 configureStore를 사용한다.
// 
const store = configureStore({
  reducer: counterSlice.reducer
});

//전역으로 액션 객체를 생성한다. 원하는 메서드만 뽑아 와 사용할 수 있게 함.
// counterSlice(createSlice의 이름)의 action 객체를 생성한다.
export const counterActions = counterSlice.actions;

export default store;
import { useState } from 'react';
import { useSelector,useDispatch } from 'react-redux';
import classes from './Counter.module.css';

//Counter.js에 전역 액션 객체를 불러와서 사용하겠다는 뜻이다.
import {counterActions} from '../store/index'

const Counter = () => {
  // UseSelector
  // 함수는 리덕스가 실행한다.
  // 원하는 값만 선택할 수 있게 함.
  // 자동으로 구독을 관리함.
  const counter = useSelector(state => state.counter);
  const show = useSelector(state => state.showCounter);
  const [value,setValue] = useState(0);
  //store에 action을 보낸다
  const dispatch = useDispatch();

  const incrementHandler = () => {
    dispatch(counterActions.increment());
  };

  const decrementHandler = () => {
    dispatch(counterActions.decrement());
  }
  const onChange = ({target}) => {
    if(!target.value){
      
      return;
    }else{
      setValue(parseInt(target.value))
    };
  
  }

  const increaseHandler = () => {
    //payload가 필요하다면 인수로 전달해준다.
    // 자동으로 액션 생성자를 생성하고 type: SOME-unique-identifier를 전달하고
    // 인자로서 실행하고자 하는 액션 메서드에 전달한 값을
    // 추가 필드명이 payload인 곳에 저장하기 때문입니다.
    dispatch(counterActions.increase(value))
  }

  const toggleCounterHandler = () => {
    dispatch(counterActions.toggoleCounter())
  };

  return (
    <main className={classes.counter}>
      <h1>Redux Counter</h1>
      {show && <div className={classes.value}>{counter}</div>}
      
      <input type="text" value={value} onChange={onChange}/>
      
      <div>
        <button onClick={incrementHandler}>Increment</button>
        <button onClick={increaseHandler}>Increment by inputValue</button>
        <button onClick={decrementHandler}>Decrement</button>
      </div>
      <button onClick={toggleCounterHandler}>Toggle Counter</button>
    </main>
  );
};

export default Counter;

0개의 댓글