[Redux] Redux - React Redux - Ducks Pattern

SangHeon·2023년 1월 24일
1

[Redux]

목록 보기
1/1
post-thumbnail

Redux

자바스크립트 앱을 위한 예측 가능한 상태 컨테이너

상태의 변화를 특정 함수(Dispatch)에 의해서만 변할 수 있게 통제해 상태변화를 예측 할 수 있게 만듬

데이터가 단방향으로 흐르도록 설계한 Flux 디자인 패턴에서 영감을 받아 자바스크립트로 구현한 구현체


Redux의 구조

3가지 원칙

  • 어플리케이션(Application)은 단일 저장소(Store)를 가진다
  • state를 수정할 수 있는 유일한 방법은 무슨일이 벌어지는지 묘사하는 액션 객체를 전달하는 것임.
  • 변화는 순수 함수로 작성되어야한다.

개념

Life Cycle

  1. UI -> 이벤트 발생 -> 이벤트 핸들러의 Dispatch 메서드 실행
  2. Dispatch(ActionCreator()) -> Store 내부의 ReducerAction객체 전달
  3. Reducer에 따라 State 업데이트 -> 새로운 State 반환 -> useSelector() 로 UI 사용
  4. 사이클 종료
    event -> ActionCreator(Action) -> Dispatch ->
    Reducer -> Store state 변경 -> UI반영

출처 : 리덕스 공식 홈페이지

주요 용어

Action : 상태 변화에 대한 의도를 표현하는 단순한 자바스크립트 객체
Action Creator : Action 객체를 정해진 틀에 맞게 리턴하는 함수
                                ㄴ컴포넌트에서 쉽게 Action 객체를 만들 수 있기 때문에 사용
Dispatch : Action 객체를 Reducer에 보내는 역할을 하는 redux store의 메서드
Store : 모든 state의 저장소
Reducer : 이전의 상태와 액션을 받아서 새로운 상태를 반환하는 순수함수
                   ㄴReducer는 감지된 Action 타입에 따라
                   이벤트를 처리하는 이벤트 리스너로도 생각할 수 있음

 

Reducer의 관리

// reducer 형태
(previousState, action) => newState;

리듀서는 기본적으로 이전 상태값과 액션을 인자로 받아
새로운 상태값을 리턴하는 함수입니다.

이러한 리듀서 하나의 파일에 모든 로직을 넣게 되면 유지보수하기 어려우므로
관심사별로 slice Reducer를 만들고 combineReducer 메서드로 slice Reducer들을 root Reducer로 만들어서 관리합니다.

const rootReducer = combineReducer({ todoSlice, countSlice })

React-Redux란?

자바스크립트 기반의 프레임워크(Vue, Angular, React 등)에서는 모두 사용할 수 있는 Redux가
React의 state, props와는 연동이 되지 않아 연동하기 위해 만들어진 라이브러리

React-Redux에서 제공하는 API를 통해 전역으로 상태를 관리할 수 있음.

Provider : react app 전체에 제공할 store를 주입하는 컴포넌트 입니다.

<Provider store={store}>
  <App />
</Provider>

useSelector : store의 state에 접근하는 hook 입니다.

const todos = useSelector(state => state.todos) // store에 저장된 state 가져옴

useDispatch : action을 reducer로 보내는 역할입니다.

// 호출
const dispatch = useDispatch();
// 사용
const eventHandler = () => {
  dispatch(ActionCreator()) // Action 생성 -> (dispatch) ->  Reducer로 전달
}

**Ducks 패턴

하나의 파일에 { Action Type, Action Creator, Reducer } 가 모두 담겨져 작성되는 패턴을 의미함
이렇게 작성된 하나의 파일은 '모듈'이라고 지칭함

기본폴더 구조

src
└── components
    ├── ...
└── pages
    ├── ...
└── redux
    ├── index.js   // root reducer
    ├── counter.js // slice 1 
    └── todo.js    // slice 2

루트 리듀서

import { combineReducers } from 'redux';
import counter from './counter';
import todo from './todo';

const rootReducer = combineReducers({ counter, todo })

export default rootReducer;

모듈 파일

// Action Type
const INCREASE = 'counter/INCREASE';
const DECREASE = 'counter/DECREASE';

// Action Creator
export const increase = () => {
  return { type: INCREASE }
}
export const decrease = () => {
  return { type: DECREASE }
}

// InitialState
const initialState = {
  count: 0,
};

// Reducer
function counterReducer(state = initialState, action) {
  if(action.type === 'INCREASE'){
    return { ...state, count: state.count + 1 }
  } else if(action.type === 'DECREASE'){
    return { ...state, count: state.count - 1 }
  } else {
    return state
  }
}

export default counterReducer;

Ducks 패턴 참조

profile
Front-end Developer

0개의 댓글