React

[ redux ] counter 만들기 코딩

유기린 2022. 8. 19. 20:52
// src > index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

// 우리가 추가할 코드
import store from "./redux/config/configStore";
import { Provider } from "react-redux";

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(

  //App을 Provider로 감싸주고, configStore에서 export default 한 store를 넣어줍니다.
  <Provider store={store}>
    <App />
  </Provider>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
//src > App.js

import React from "react";
import { useDispatch, useSelector } from "react-redux";

import { minusOne, plusOne } from "./redux/modules/counter";

const App = () => {
  const dispatch = useDispatch(); //dispatch 생성
  const number = useSelector((state) => state.counter.number);

  console.log(number);
  return (
    <div>
      {number}
      <button
        // 이벤트 핸들러 추가
        onClick={() => {
          // 마우스를 클릭했을 때 dispatch가 실행되고, ()안에 있는 액션객체가 리듀서로 전달된다.
          dispatch(plusOne());
        }}
      >
        + 1
      </button>

      <button
        onClick={() => {
          dispatch(minusOne());
        }}
      >
        - 1
      </button>
    </div>
  )

}

export default App;
// src > redux > config > configStore.js

import { createStore } from "redux";
import { combineReducers } from "redux";
import counter from "../modules/counter";

const rootReducer = combineReducers({
  counter: counter,
});
const store = createStore(rootReducer);

export default store;
// src > redux > modules > counter.js

const PLUS_ONE = "PLUS_ONE"; // 액션객체의 type value를 상수로 생성해서 관리
const MINUS_ONE = "MINUS_ONE"; // 액션 value를 상수로 만듬


/// Action Creator
// 액션객체를 반환하는 함수 생성
// export 가 붙는 이유는 plusOne()는 밖으로 나가서 사용될 예정이기 때문입니다.
export const plusOne = () => {
  return {
    type: PLUS_ONE, // type에는 위에서 만든 상수로 사용 (vscode에서 자동완성 지원)
  };
};

export const minusOne = () => {
  return {
    type: MINUS_ONE,
  };
};


// 초기 상태값
const initialState = {
  number: 0,
};

// 리듀서
const counter = (state = initialState, action) => {
  console.log(action)
  switch (action.type) {
    // PLUS_ONE이라는 case를 추가한다.
    // 여기서 말하는 case란, action.type을 의미한다.
    // dispatch로부터 전달받은 action의 type이 "PLUS_ONE" 일 때
    // 아래 return 절이 실행된다. 
    // case "PLUS_ONE":
    case PLUS_ONE:
      return {
        // 기존 state에 있던 number에 +1을 더한다.
        number: state.number + 1,
      }
    // action.type이 MINUS_ONE 일 때 새로운 state 반환
    case MINUS_ONE:
      return {
        number: state.number - 1,
      };
    default:
      return state;
  }
};

// 모듈파일에서는 리듀서를 export default 한다.
export default counter;