리액트

[React]Redux

민ズl 2024. 11. 11. 14:00

context api 단점

1. 복잡한 설정

context가 많으면 밑에 코드처럼 복잡해지고, 유지보수가 어렵다

<AuthContextProvier>
	<ThemeContextProvider>
		<UIInteractionContextProvider>
			<MultiStepFormContextProvider>
...

 

2. 성능

context는 Provider 하위의 모든 컴포넌트를 리랜더링, 불필요하게 업데이트될수 있음


redux 설명

store

  • 애플리케이션의 전체 상태 트리를 보유하는 중앙 저장소
  • 각 컴포넌트가 스토어의 특정 상태를 "구독"
  • 직접 조작x

리듀서 함수

  • 이전 상태와 액션 객체를 받아 새로운 상태를 반환하는 순수 함수
  • input : old state + dispatched Action => Output : New State Object
  • *reducer 메소드, useReducer 훅이랑 다름

action

  • 상태 변경에 대한 정보를 포함한 객체
  • 액션 객체는 type 속성을 반드시 가져야 하며, 추가적인 데이터를 payload로 담을 수 있음
  • 컴포넌트가 dispatch를 통해 스토어에 전달
// src/modules/counter.js

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

// 리듀서
const counter = (state = initialState, action) => {
  switch (action.type) {
    case "PLUS_ONE":
      return {
        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;

 

디스패치

  • 액션을 발생 시키는 것
  • useDispatch()훅을 사용
  • 액션을 파라미터로 전달
  • 액션객체 type의 value는 대문자로 작성

작동방식

dispatch된 액션을 스토어로 전달 =>

스토어는 해당 액션을 리듀서에 넘겨 상태 변경 로직을 처리 =>

리듀서는 이전 상태와 액션을 기반으로 새로운 상태를 생성하여 반환 =>

스토어가 이를 기존 상태와 교체

https://infinijith.com/blog/react/react-redux


리덕스 사용방법

1. 설치

yarn add redux react-redux

# 아래와 같은 의미
yarn add redux
yarn add react-redux

2. store 생성

import { createStore } from "redux";
import { combineReducers } from "redux";

const rootReducer = combineReducers({}); 
const store = createStore(rootReducer); 

export default store;

3. 최상단 파일에 store 지정

import store from "./redux/config/configStore";
import { Provider } from "react-redux";

const root = ReactDOM.createRoot(document.getElementById("root"));

root.render(
  <Provider store={store}> 
    <App />
  </Provider>
);

4. 모듈에 reducer function 생성(state,action)

// src/redux/modules/counter.js

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

// 리듀서
const counter = (state = initialState, action) => {
  switch (action.type) {
    default:
      return state;
  }
};

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

* 생성한 모듈을 store에 연결이 잘 됐는지 확인하는 법 (useSelector)

import { useSelector } from "react-redux";

const App = () => {
  const counterStore = useSelector((state) => state);
  console.log(counterStore); 

  return <div></div>;
}

 

action creator

액션 객체의 value를 변경할일이 생길때를 위해

1. 액션 객체를 한곳에서 관리할 수 있도록 함수와 액션 value를 상수로 만들기

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

2. action creator를 import하기

3. dispatch()에 있던 액션객체를 지우고 action creator넣기

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

 

payload

reducer에 얼만큼의 값을 어떻게 해! 라고 할 때, 이 얼만큼의 값을 전달

// src/redux/modules/counter.js

// Action Value
const ADD_NUMBER = "ADD_NUMBER";

// Action Creator
export const addNumber = (payload) => {
  return {
    type: ADD_NUMBER,
    payload: payload,
  };
};
// 리듀서

const counter = (state = initialState, action) => {
  switch (action.type) {
    case ADD_NUMBER:
      return {
// state.number (기존의 nubmer)에 action.paylaod(유저가 더하길 원하는 값)을 더한다.
        number: state.number + action.payload,
      };
    default:
      return state;
  }
};

'리액트' 카테고리의 다른 글

[React]TanStack Query  (2) 2024.11.28
[React]axios  (0) 2024.11.26
[React]context api  (0) 2024.11.11
[React]form태그 비제어  (0) 2024.11.06
[React]memo(React.memo), useCallback,useMemo  (0) 2024.11.05