Redux

홍준섭·2022년 9월 15일

react

목록 보기
11/29

동기

많은 상태를 자바스크립트 코드로 관리해야 한다. 그러나 항상 변하는 상태를 관리하기란 어렵다. 상태가 복잡해지면 상태가 언제, 왜, 어떻게 업데이트 할지 제어할 수 없다. 더하여 프론트엔드 제품 개발에 있어서 Optimistic update, 서버렌더링, 라우트가 일어나기 전에 데이터 가져오기 등 고려해야 할 요소가 늘어나고 있다. Redux는 상태 변화가 일어나는 시점에 제약을 두어 상태 변화를 예측 가능하게 만들고자 한다.

리덕스 관련 키워드 개념

  • 액션
    상태에 어떠한 변화가 필요하면 액션이 발생.
{
  type: 'TOGGLE_VALUE'
}

액션 객체는 다음과 같은 형식으로 이루어짐. 액션 객체는 type필드를 반드시 가지고 있어햐 한다. 이 값을 액션의 이름이라고 생각하면 된다. 그리고 그 외의 값들은 나중에 상태 업데이트르 할 때 참고해야 할 값이며, 작성자 마음대로 넣을 수 있다.

  • 액션 생성 함수
    액션 생성 함수는 액션 객체를 만들어 주는 함수입니다.
function addTodo(data){
	return{
    	type:'ADD_TODO',
        data
    };
}

어떤 변화를 일으켜야 할 때마다 액션 객체를 만들어야 하는데 이를 함수로 만들어서 관리

  • 리듀서
    리듀서는 변화를 일으키는 함수이다. 액션을 만들어서 발생시키면 리듀서가 현재 상태와 전달받은 액션 객체를 파라미터로 받아온다. 그리고 두 값을 참고하여 새로운 상태를 만들어서 반환해 준다.

  • 스토어
    한 개의 프로젝트는 한개의 스토어만 가질 수 있다. 스토어 안에는 현재 애플리케이션 상태와 리듀서가 들어가 있으며, 그 외에도 몇 가지 중요한 내장 함수를 지닌다.

  • 디스패치
    디스패치는 스토어의 내장 함수 중 하나이다. 디스패치는 액션을 발생시키는 것이라고 이해하면 된다. 이 함수는 dispatch(action)과 같은 형태로 액션 객체를 파라미터로 넣어서 호출한다. 이 함수가 호출되면 스토어는 리듀서 함수를 실행시켜서 새로운 상태를 만들어준다.

  • 구독
    구독도 스토어의 내장 함수 중 하나이다. subscribe 함수 안에 리스너 함수를 파라미터로 넣어서 호출해 주면, 이 리스너 함수가 액션이 디스패치되어 상태가 업데이트될 때마다 호출된다.

전체 과정: dispatch(action) -> 리듀서 실행, 새로운 상태 만들어서 반환 -> subscribe 함수 안의 리스너 함수 호출

리덕스의 세 가지 규칙

  • 단일 스토어
    하나의 애플리케이션 안에는 하나의 스토어가 들어 있다. 애플리케이션의 모든 상태는 하나의 저장소 안에 하나의 객체 트리 구조로 저장된다
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)
profile
개발 공부중입니다

0개의 댓글