글 작성자: 망고좋아
반응형

🎯 리덕스

  • 앱 전체 상태를 쉽게 관리하기 위한 라이브러리
  • Redux의 많은 개념들이 Flux pattern에서 차용되었다,
  • 주로 React 앱과 같이 사용한다.
  • redux.js.org에서 수많은 문서를 참고할 수 있고, 웹상에 Redux를 활용한 앱 구축 사례가 많다.

 

📝 언제 Redux를 써야 하는가

  • 앱 전체의 상태 관리가 필요할 때
    • useState, useReducer, useContext는 정해진 규약이 딱히 없다.
    • 하지만 Redux는 정해진 규약이 있어서 협업하기 좋다. ⇒ 패턴이 정해져 있다.
  • 복잡한 비동기 처리가 있는 상태 관리가 필요할 때
    • redux-thunk
    • redux-saga
  • 앱의 상태가 복잡하고, 이를 체계적으로 관리하고 싶을 때
  • 상태 관리 패턴을 도입하여, 여러 개발자와 협업하고 싶을 때
  • logger, devtool 등을 활용하여 상태를 관리할 필요가 있을 때

 

📝 핵심 원칙

  • Single source of truth : Store는 단 하나이며, 모든 앱의 상태는 이곳에 보관된다.
  • Immutability : 상태는 오로지 읽을 수만 있다. 변경하려면 모든 상태가 변경되어야 한다.
  • Pure function : 상태의 변경은 어떠한 사이드 이펙트도 만들지 않아야 한다.

 

📝 Action

const action1 = {
    type: 'namespace/getMyData',
    payload : {
        id: 123
    }
}
  • Action(액션)은 스토어에서 상태 변화를 일으킬 때 참조하는 객체이다.
    • Action은 상태의 변경을 나타내는 개념이다.
  • 즉, 애플리케이션에서 스토어로 보내는 데이터의 묶음이다.
  • 액션은 스토어의 유일한 정보원이다.
  • 액션은 평범한 자바스크립트 객체다.
  • 액션은 반드시 어떤 형태의 액션이 실행될지 나타내는 type 속성을 가져야 한다.
    • 어떤 형태든지 상관없으나 주로 type, payload를 포함하는 JavaScript 객체다.
  • type은 일반적으로 문자열 상수로 정의된다.
  • 이 payload를 이용해 상태를 변경하는 것 외에는 다른 어떤 것이 일어나면 안 된다는 의미를 내포하고 있다.
  • 액션은 큰 상태 변경을 만들기보다는 잘게 쪼개 놓은 작은 상태의 변경을 나타내는 것이 좋다. 이 작은 상태들을 모다서 복합적인 상태를 만드는 것이 좋다.

 

📝 Action Creator(액션 생성 함수)

const addObj = (id) => ({
    type: 'namespace/getMyData',
    payload : {
        id: String(id).slice(1)
    }
})
  • Action을 생성하는 함수
  • 액션을 좀 더 편하게 사용하기 위해서 액션 생성 함수를 사용한다. 이 함수는 액션 타입의 상수 값으로 정의해야 한다.
  • 직접 Action을 생성하는 것보다 Action Creator를 활용하면 재사용성이 좋고, 하나의 레이어를 추가할 수 있다.

 

📝 Store

const store = createStore(reducer, initialState)
  • 앱 전체의 상태를 보관하는 곳
  • Action에 따라 reducer에서는 새로운 상태를 만들어내며, Store는 그 상태를 저장한다.
  • Store의 상태는 불변하며, 매 액션이 발생할 때마다 새로운 객체가 만들어진다.
    • reducer → store로 들어가는 건 새로운 객체다.

 

📝 Reducer

const reducer = (state, action) => {
    switch (action.type) {
        case 'namespace/getMyData':
            const obj = { id: action.payload.id }
            return { ...state, obj }
        default:
            return state
    }
}

const store = createStore(reducer, initialState)
  • 상태(state)에 변화를 일으키려면 리듀서 함수가 필요하다.
  • 액션은 무언가 일어난다는 사실을 기술하지만, 그 결과 애플리케이션의 상태가 어떻게 바뀌는지는 특정하지 않는다. ⇒ 특정하는 일은 리듀서가 해야 할 일이다.
  • 리듀서는 두 개의 파라미터를 받으며 첫 번째는 현재 상태이며, 두 번째는 액션 객체다.
  • 초기 상태(state)는 리듀서에서 생성해야 하며, 이후 변경된 state는 덮어 씌어서 사용된다.
  • Action을 받아 새로운 State를 만든다.
  • (state, action) => state의 인터페이스를 따른다.
  • Reducer에서는 상태를 변경하면 안 되고, 새로운 상태를 리턴해야만 한다.
  • 상태 변경 시 사이드 이펙트가 없어야 한다.
    • console.log나 axios가 들어가면 안 된다. → action을 reducer에 보내기 전에 다 해준 다음에 결과를 action에 넣어줘야 된다.

 

📕 Reducer의 특징

  • 리듀서 함수는 이전 state와 액션 객체를 파라미터로 받아야 한다.
  • 리듀서는 이전의 state는 변경하지 않고, 변화를 일으킨 새로운 state 객체를 덮어 씌우고 반환해야 한다.
  • 똑같은 파라미터로 호출된 리듀서 함수는 언제나 똑같은 결괏값을 반환해야 한다.

 

📝 Dispatch

function MyApp() {
    const dispatch = useDispatch()
    return (
        <button onClick={() => 
            dispatch(addObj(1234)
        )}
        >Submit</button>
    )
}
  • Action을 redux로 보내는 함수
  • dispatch 후에 action은 middleware를 거쳐 reducer에 도달한다.
  • 디스패치는 Action Creator를 넘기는 게 아니라 Action obj를 넘겨야 한다.
  • dispatch(action) → middleware → action → reducer

 

📝 Selector

function MyApp() {
    const obj = useSelector(state    => state.obj)
    return (
        <div>
            {JSON.stringify(obj)}
        </div>
    )
}
  • 특정 state 조각을 store로부터 가져오는 함수
  • store의 state는 raw data를 저장하고, 계산된 값 등을 selector로 가져오는 등의 패턴을 구사할 때 유용하다.
반응형

'프로그래밍 > React' 카테고리의 다른 글

[Redux] redux-toolkit  (0) 2022.01.17
[Redux] Redux의 구조  (0) 2022.01.17
[React Redux] React Redux란?  (0) 2022.01.17
[Redux] 리덕스 데이터 흐름  (0) 2022.01.17
[React] Flux Pattern  (0) 2022.01.16