Redux 맛보기!!!

김인태·2022년 7월 3일
0

😜Redux를 알아보자 !

Redux란 무엇인가요?

  • 자바스크립트 상태관리 라이브러리입니다.
  • 굉장히 많은 기업들이 상태관리를 redux를 통해서 하고 있으며 React와 묶여있다고 생각하는 분들이 많지만 사실 javascript를 기반으로하는 vue.js, vanilla js에도 사용할 수 있습니다!

💫왜 쓰나요?

  • 자식 컴포넌트들 간의 다이렉트 데이터 전달은 불가능 합니다.그래서 자식 컴포넌트들 간의 데이터를 주고 받을 때는 상태를 관리하는 부모 컴포넌트를 통해서 주고 받습니다.
  • 그런데 자식이 많아진다면 상태 관리가 매우 복잡해질 것입니다. 상태를 관리하는 상위 컴포넌트에서 계속 내려 받아야하기 때문입니다.

Redux 3가지 원칙.

  • 진실은 하나의 근원으로부터​
    애플리케이션의 모든 상태는 하나의 저장소 안에 하나의 객체 트리 구조로 저장됩니다.
console.log(store.getState())

/* Prints
{
  visibilityFilter: 'SHOW_ALL',
  todos: [
    {
      text: 'Consider using Redux',
      completed: true,
    },
    {
      text: 'Keep all state in a single tree',
      completed: false
    }
  ]
}
*/
  • 상태는 읽기 전용이다​
    상태를 변화시키는 유일한 방법은 무슨 일이 벌어지는 지를 묘사하는 액션 객체를 전달하는 방법뿐입니다.
store.dispatch({
  type: 'COMPLETE_TODO',
  index: 1
})

store.dispatch({
  type: 'SET_VISIBILITY_FILTER',
  filter: 'SHOW_COMPLETED'
})
  • 변화는 순수 함수로 작성되어야한다​
    액션에 의해 상태 트리가 어떻게 변화하는 지를 지정하기 위해 프로그래머는 순수 리듀서를 작성해야합니다.
function visibilityFilter(state = 'SHOW_ALL', action) {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter
    default:
      return state
  }
}

function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case 'COMPLETE_TODO':
      return state.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: true
          })
        }
        return todo
      })
    default:
      return state
  }
}

import { combineReducers, createStore } from 'redux'
const reducer = combineReducers({ visibilityFilter, todos })
const store = createStore(reducer)

참조 : https://ko.redux.js.org/understanding/thinking-in-redux/three-principles [redux 공식 홈페이지]

😏원칙은 알겠고... 그래서 어떻게 쓰는건데?

Redux에서 중요한 개념들 store, reducer, action,dispatcher을 알아보겠습니다.

Action

  • Action이란 상태 변화에 대한 의도를 표현하는 단순한 자바스크립트 객체입니다.
  • Action Creator는 이러한 Action 객체를 정해진 틀에 맞게 리턴하는 단순한 함수이고, Action을 reducer로 보내는 역할을 하는 건 아닙니다.
  • Action은 Store에 담긴 데이터를 변형시킬 수 있는 유일한 방법입니다.
  • store.dispatch 함수의 인자로 담겨 reducer에 어떻게 store를 변경시킬 것인지에 대한 정보를 제공 하는 역할을 하고 object 형태로 되어있습니다.
const ADD_TODO = {
  type: "ADD_TODO",
  payload: { content: "출근하기", priority: 1 }
}

Store?

  • Redux 앱 전체의 상태로 보통 깊게 중첩되어 있는 객체입니다.
  • store에서 관리되고, store.getState()로 읽어올 수 있습니다.
  • 항상 직렬화(Serialization) 가능해야 하기 때문에 JSON으로 쉽게 변환할 수 없는 것들은 제외하는게 좋습니다(ex. 함수, Promise 등)

Reducer?

  • Reducer는 (previousState, action) => newState의 형태를 가지고, 순수함수이며 예측 가능해야 합니다.
  • Reducer는 업데이트 되기 이전의 Store를 기반으로 새로 받은 Action에 미리 준비된 로직을 처리해 새로운 Store를 리턴하는 함수입니다. 즉, Reducer는 감지된 Action 타입에 따라 이벤트를 처리하는 이벤트 리스너로도 생각할 수 있습니다.
  • Reducer의 이름이 reducer 인 이유는, Array.prototype.reduce의 역할이 그러하듯 값을 받아 하나의 결과물로 줄이기 때문입니다.
const cart = [
  { id: 1, name: "청바지", price: 10000, quantity: 2 },
  { id: 2, name: "반바지", price: 10000, quantity: 1 },
  { id: 3, name: "반팔", price: 10000, quantity: 2 },
];

const totalPrice = cart.reduce((acc, cur) => {
  return acc + cur.price * cur.quantity
}, 0);

🐴주의사항!

  • 불변성을 지켜 업데이트 해야 합니다.
  • 기존 값을 직접 수정하면 안됩니다. React에서 setState로 그렇게 해왔듯 기존 값을 복사하고 새롭게 복사된 값을 덮어쓰는 방식으로 업데이트 해야 합니다.
  • Reducer 내부에서 비동기나 여타 순수하지 않은 로직(Side Effect)을 처리하면 안됩니다.
    ex. Promise(fetch), Math.random(), new Date()

Dispatcher?

  • Action 객체를 Reducer에 보내는 역할을 하는 함수. store.dispatch() 형태로 제공됨.
  • 기본 dispatch 함수는 반드시 동기적으로 처리되어야 함.
  • 만약 비동기 Action이 필요하다면 비동기 처리가 완료된 이후에 Action을 - Dispatch 하거나, 미들웨어(Action이 Reducer로 들어가기 전에 거쳐가는 곳)를 활용해 비동기 처리를 해줘야 합니다.

redux를 안지 얼마 되지않아서 전역변수들을 효율적으로 잘 관리 할 수 있을지 모르겠지만 잘 활용하면 굉장한 도움이 될 것같다. 또 아쉬운점은.. 사실 state가 익숙해진지가 얼마되지 않았지만.. 그래도 배움은 재밌다!!!

profile
새로운 걸 배우는 것을 좋아하는 프론트엔드 개발자입니다!

0개의 댓글