als982001 2023. 2. 24. 11:02

Redux

1. Redux

  • Redux는 상태 관리 라이브러리 중 하나.
  • 전역 상태를 관리할 수 있는 저장소인 Store를 제공함.
  • Redux의 상태 관리 순서 (Action -> Dispatch -> Reducer -> Store)
    1. 상태가 변경되어야 하는 이벤트가 발생하면, 변경될 상태에 대한 정보가 담긴 Action 객체가 생성됨.
    2. Action 객체는 Dispatch 함수의 인자로 전달
    3. Dispatch 함수는 Action 객체를 Reducer 함수로 전달해줌
    4. Reducer 함수는 Action 객체의 값을 확인하고, 그 값에 따라 전역 상태 저장소 Store의 상태를 변경
    5. 상태가 변경되면, React는 화면을 다시 렌더링함.

 

2. Store

store라고 검색하니까 나온 이미지

  • 상태가 관리되는 오직 하나뿐인 저장소 역할
  • createStore 메서드를 활용해, Reducer를 연결해서 Store를 생성할 수 있음

 

3. Reducer

상태 변화를 보여주는 이미지. Reducer와 크게 관련 있는지는 모르겠다

  • Dispatch에게서 전달받은 Action 객체의 type 값에 따라 상태를 변경시키는 함수
  • Reducer는 외부 요인으로 인해 기대한 값이 아닌 엉뚱한 값으로 상태가 변경되는 일이 없어야 하기 때문에  Reducer는 순수 함수이어야 함.
  • 여러 개의 Reducer를 사용할 경우 combineReducers 메서드를 이용해 하나의 Reducer로 합칠 수 있음
import { combineReducers } from 'redux';

const reducers = combineReducers({
  counterReducer,
  selecterReducer,
  ...
});

 

4. Action

Action이라 검색하니 나온 이미지

  • 어떤 액션을 취할 것인지 정의해 놓은 객체
  • key는 type, value는 문자열로 구성. (예: { type: "INCREASE" }
  • payload가 필요할 경우, 작성하면 됨 (예: { type: "INCREASE", payload: 2 }
  • 일반적으로  Action 객체를 직접 작성하지 않고, 이를 생성하는 함수를 만들어 이용하는데, 이를 액션 생성자(Action Creator)라고 함

 

5. Dispatch

뭔가를 보낸다는 느낌의 이미지

  • Reducer로 Action을 전달하는 함수
  • 전달 인자로 Action 객체가 전달됨.
  • Action 객체를 전달받은 Dispatch 함수는 Reducer를 호출

 

6. Redux Hooks

  1. useDispatch(): Action 객체를 Reducer로 전달해주는 Dispatch 함수를 반환하는 메서드
  2. useSelector(): 컴포넌트와 state를 연결하여  Redux의 state에 접근할 수 있게 해주는 메서드

 

7. Redux의 세 가지 원칙

  1. Single source of truth: 동일한 데이터는 항상 같은 곳에서 가지고 와야 한다.
  2. State is read-only: 상태는 읽기 전용이다. Redux의 상태는 직접 변경할 수 없다.
  3. Changes are made with pure functions: 변경은 순수 함수로만 가능하다.

 

8. 예시

import { Provider } from 'react-redux';
import { legacy_createStore as createStore } from 'redux';
import { useDispatch } from 'react-redux';

export const INCREASE = 'INCREASE';
export const DECREASE = 'DECREASE';

// Action 객체를 반환하는 함수
export const increase = () => {
  return {
    type: INCREASE,
  };
};

// 1. 적절한 reducer를 만든다.
export const counterReducer = (state = initialState, action) => {
  switch (action.type) {
    case INCREASE:
      return state + 1;
    case DECREASE:
      return state - 1;
    default:
      return state;
  }
};

// 2. createStore를 통해 적절한 store를 만든다.
export const store = createStore(counterReducer);

// 3. index.js의 <App />을 Provider로 감싼다.	 (상황에 따라 다르다)
// index.js
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);

// 4. 상태를 변경시킬 경우, dispatch를 이용해 Action 객체를 전달한다.
const dispatch = useDispatch();
const state = useSelector((state) => state);
  
const plusNum = () => {
	dispatch(increase());
 };