개발일지/React

Redux 입문하기 (with React.js)

zzoo-ppaamm 2021. 9. 28. 21:23

해당 글은 생활코딩의 Redux 강의 내용을 정리하며 작성하였습니다.

https://opentutorials.org/module/4078

 

Redux

수업소개 예측 가능한 애플리케이션의 상태 저장소인 Redux를 다루는 수업입니다. 이 수업에서는 순수한 웹기술인 HTML, JavaScript와 Redux만을 이용해서 웹애플리케이션을 만들어 볼 것입니다.  이

opentutorials.org

 

Why Redux ?

1. logic을 재사용함 => logic 횟수를 감소시킨다. 

2. redux-dev-tools를 사용하면 '시간여행'이 가능하다!

3. component 간의 의존성을 낮출 수 있다. => component들은 하나의 store에 집중하면 된다.

 

What is Redux ?

 

Redux 구조

 

 

dispatch :  ③ Reducer를 호출 → ④ state값 변경
               ⑤ 끝나면 subscribe 함수 호출 ⑥ render 함수 호출

 

subscribe : state 값이 바뀔 때마다 render ()

 

state : 직접 접근 절대 X !!!

 

store.dispatch(action);

action : {
    type : ~~,
    payload : { ... }
}

 

How to Redux ?

redux는 react 전용 라이브러리가 아니어서 redux 외에 추가적으로 useDispatch와 useSelector를 지원하는 react-redux를 install 해야한다.

 

 

Counter 예제)

action과 action을 생성하는 함수, reducer를 하나의 파일에 구현하는 Duck's Pattern을 적용하였다.

 

 

reducers/Counter.js

// action
const INCREASE = "COUNTER/INCREASE";
const DECREASE = "COUNTER/DECREASE";

// action 생성 함수
export const increaseNum = () => {
  return { type: INCREASE };
};

export const decreaseNum = () => {
  return { type: DECREASE };
};

// 초기 생성
const initState = {
  num: 0,
};

// reducer
export default function counterReducer(state = initState, action) {
  switch (action.type) {
    case INCREASE:
      return {
        ...state,
        num: state.num + 1,
      };
    case DECREASE:
      return {
        ...state,
        num: state.num - 1,
      };
    default:
      return {
        ...state,
      };
  }
}

 

CounterControlContainer.jsx

import React from "react";
import { useDispatch } from "react-redux";
import { increaseNum, decreaseNum } from "./reducers/Counter";
const CounterControllContainer = () => {
  const dispatch = useDispatch();

  const handleIncrease = () => {
    dispatch(increaseNum());
  };

  const handleDecrease = () => {
    dispatch(decreaseNum());
  };

  return (
    <div>
      <button onClick={handleIncrease}>+</button>
      <button onClick={handleDecrease}>-</button>
    </div>
  );
};

export default CounterControllContainer;

 

CounterPresenter.jsx

import React from "react";
import { useSelector } from "react-redux";
const CounterPresenter = () => {
  const count = useSelector((state) => state.num);
  return <div> 현재 카운트 : {count}</div>;
};

export default CounterPresenter;

 

App.js

import React from "react";
import CounterControlContainer from "./CounterControlContainer";
import CounterPresenter from "./CounterPresenter";

const App = () => {
  return (
    <>
      <CounterPresenter />
      <CounterControlContainer />;
    </>
  );
};

export default App;

 

index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import { createStore } from "redux";
import { Provider } from "react-redux";
import counterReducer from "./reducers/Counter";

const store = createStore(counterReducer);
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

serviceWorker.unregister();