본문 바로가기
코딩이야기/Redux

[Redux] 리덕스 사용법 및 예제 (1)

by TaeHyeon0412 2024. 7. 5.

https://taehyeon-smilestudy.tistory.com/48

 

[Redux] 리덕스 설치하기! (feat. 설치하는 이유는?)

리덕스(Redux)가 필요한 이유 useState의 불편함조부모 컴포넌트에서 손자 컴포넌트로 값을 보낼 때 반드시 부모 컴포넌트를 거쳐 전달해야 되는 문제점이 있습니다. (조부모->부모->손자) 부모

taehyeon-smilestudy.tistory.com

 

리덕스 설치와 기본 설정이 끝났습니다.
다음은 리덕스를 이용한 간단한 예제를 볼게요.

 

1. 모듈을 만들어 줍니다.

//sre / redux / modules / counter.js

// 초기 상태값(state)
const init ={
 number:0
};

//리듀서: "state"에 변화를 일으키는 함수
//즉, state를 action의 type에 따라 변경하는 함수

//input : state와 action
const counter = (state = init, action)=>{
	switch (action.type){        
        //기본값
		default:
		     return state;
}

export default counter;

 

설정코드는 이해할 필요가 없는 코드들 입니다, 코드 분석 금지 ❌
설정 코드를 작성하는 이유는 리덕스를 만든 리덕스팀에서 이렇게 설정을 하라고 안내하고 있기 때문입니다.

 

2. 만든 리듀서를 configStore.js에 import 해줍니다.

// 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;

 

이렇게 configStore에 reducer를 추가하면 스토어와 모듈이 연결됩니다.
스토어와 모듈을 연결시키는 코드는 모듈을 추가할 때마다 똑같이 진행하면 됩니다.

이제 연결이 잘 되었는지 확인을 해야 되는데 
컴포넌트에서 스토어를 직접 조회하는 방법이 있습니다.
컴포넌트에서 리덕스 스토어를 조회하고자 할때는 useSelector라는 ‘react-redux’의 훅을 사용해야 합니다

3. useSelector의 사용법은 아래와 같습니다.

import { useSelector } from "react-redux"; 

const data = useSelector((state)=>{               //state는 configStore에 있는 모든 state입니다.	
	return state
});

console.log("data", data);

 

만약 특정 state만 가져오고 싶다면?

import { useSelector } from "react-redux"; 

const number = useSelector((state)=>{               //state는 configStore에 있는 모든 state입니다.
	return state.counter                          //state중에 counter에 있는 데이터만 가져옵니다.
});

console.log("number", number);

 

App.js에 추가

// src/App.js

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

const App = () => {
  const counterStore = useSelector((state) => state); // 추가
  console.log(counterStore); // 스토어를 조회

  return <div></div>;
}

export default App;

이렇게 확인할 수 있습니다.

 

이제 Action Creator, dispatch를 이용하여 예제를 완성 시켜보겠습니다.

Action Creator를 사용한 예시 👇

//sre / redux / modules / counter.js

// 추가된 코드 👇 - 액션 value를 상수들로 만들어 줍니다. 보통 이렇게 한곳에 모여있습니다.
const PLUS_ONE = "PLUS_ONE";
const MINUS_ONE = "MINUS_ONE";


// 추가된 코드 👇 - Action Creator를 만들어 줍니다. 
export const plusOne = () => {
  return {
    type: PLUS_ONE,
  };
};

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


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

// 리듀서
const counter = (state = initialState, action) => {
  switch (action.type) {
    case PLUS_ONE: // case에서도 문자열이 아닌, 위에서 선언한 상수를 넣어줍니다. 
      return {
        number: state.number + 1,
      };
    case MINUS_ONE: // case에서도 문자열이 아닌, 위에서 선언한 상수를 넣어줍니다. 
      return {
        number: state.number - 1,
      };
    default:
      return state;
  }
};


export default counter;

/*Action Creator를 사용했을때 type를 바꿔야 되는 경우에는 
const PLUS_ONE = "PLUS_ONE"; " " 부분만 바꾸면 되어 관리가 용이합니다.
*/

 

Action Creator를 사용하지 않은 예시 👇

switch (action.type) {
    case "PLUS_ONE":                   //action 개체 안에 있는 type "이름"을 써줌
      return {
        number: state.number + 1,
      };

    case "MINUS_ONE":
      return {
        number: state.number - 1,
      };
    default:
      return state;
  }
};

/*이렇게 하지 않는 이유
case "PLUS_ONE" 이렇게 type을 하드코딩하게 되면 
type이름을 변경해야 될 때 파일을 전부 찾아가서 바꿔야 되는 사태가 발생하기 때문에
action creater로 바꿔서 사용해주어야 합니다.*/

 

Action Creatordispatch해서 가져오기

// src/App.js

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

// 사용할 Action creator를 import 합니다.
import { minusOne, plusOne } from "./redux/modules/counter";

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

  return (
    <div>
      {number}
      <button
        onClick={() => {
          dispatch(plusOne());      //Action creator를 가져옴
        }}
      >
        + 1
      </button>
      {/* 빼기 버튼 추가 */}
      <button
        onClick={() => {
          dispatch(minusOne());    //Action creator를 가져옴
        }}
      >
        - 1
      </button>
    </div>
  );
};

export default App;

 

Action creator를 사용하는 이유

 

bindActionCreators | Redux

API > bindActionCreators: wrapping action creators for dispatching

redux.js.org

 

결과물

 

다음은 redux의 PayloadDucks 패턴을 알아보고 적용해 보겠습니다.