Redux

이동환·2020년 10월 12일
2

TIL

목록 보기
41/74

Redux (공식문서)

: Redux는 한마디로 상태관리 라이브러리이다.
리덕스가 생겨난 이유는 SPA(single page application)에서 많은 state를 가지게 되고있다. 이런 state를 트리 구조중 하위 브랜치에 state를 보낼경우와 여러 브랜치가 한 state를 사용할 경우 복잡해지는 경우가 많기 때문에 Redux는 이 모든 state를 저장하고 있는 store라고 말 할 수 있다.

Redux의 3가지 원칙

  1. Single source of truth
    : 하나의 저장소(store)가 존재하며, 이 저장소(store)에는 애플리케이션의 모든 상태들이 객체 트리 구조로 저장되어 있다.

  2. State is read-only
    : state는 읽기전용이다. 읽기 전용 상태를 변화시키기 위해서는 무슨 일이 벌어지는 지를 묘사하는 액션 객체를 전달하는 방법뿐입니다.

  3. Changes are made with pure functions
    : 액션에 의해 상태 트리가 변경(change)시키기 위해서 순수함수인 리듀서(reducer)를 작성해야한다. 이 리듀서는 그저 이전 상태와 액션을 받아서 다음 상태를 반환하는 순수함수다. 새로운 상태객체를 생성해서 반환해야한다.

Action(액션)

: 액션은 애플리케이션에서 저장소로 보내는 데이터 묶음이다. 액션은 자바스크립트 객체이다. 액션은 반드시 어떤 형태의 액션이 실행될지 나타내는 type 속성을 가져야 한다. 이 type(타입)은 일반적으로 문자열 상수(const)로 정의됩니다. 여러분의 앱이 충분히 커지면 타입들을 별도의 모듈로 분리할수도 있습니다.
store.dispatch() 을 통해서 보낼 수 있다.

사용법

const ADD_TODO = 'ADD_TODO'
{
  type: ADD_TODO,     // 반드시 type이 존재 해야한다. 이 외는 자유
  text: 'Build my first Redux app'
}
import { ADD_TODO, REMOVE_TODO } from '../actionTypes'

보일러 플레이트란 ?(참고 블로그)
기초가 되는 templete를 boilerplate라고 부른다.
쉽게 풀어서 이야기하면, 어떠한 컴포넌트를 만들었을때, 변경하지 않고, 계속 사용이 가능한 것(컴포넌트)를 보일러 플레이트라고 말한다.

액션 생산자

: 액션 생성자란, 액션을 만드는 함수다. (액션과 액션 생성자는 다르다.)

사용법

function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}

reducer(리듀서)

: reducer는 액션(객체)를 받아서 새로운 state(객체)를 반환하는 역할을 한다.

여기까지를 흐름으로 간단하게 정리해 보면

  1. store에 모든 state들이 저장되어있다.
  2. react component가 state를 요구한다.
  3. action에서 dispatch(action)을 통해서 reducer로 전달한다.
  4. 순수 함수인 reducer에서 action을 받아서 새로운 객체(새 상태)를 반환한다.
  5. store에 새 상태를 넘긴다.

사용법
: reducer는 인자를 두개를 받는다. 첫번째인자는 이전 상태(previous state) 두번째인자는 액션(action)이다.

이때 주의해야할점.

  • 인수들을 변경해서는 안된다.
  • API호출이나 라우팅처럼 사이드 이펙트를 야기하는것들을 사용하면 안된다.
  • Date.now()Math.random() 같이 순수하지 않은 함수를 호출하면 안된다.
  • spread syntax나 assign을 사용하여 새로운 객체를 리턴해야한다.
import { SET_USERNAME, SET_DARK_MODE } from "파일 경로";
const initialState = {
  currentUser: { name: "Guest" },
  darkMode: false,
};
const settingReducer = (state = initialState, action) => {
  switch (action.type) {
    case SET_USERNAME:
      return { ...state, currentUser: { name: action.name } };
    case SET_DARK_MODE:
      return { ...state, darkMode: action.value };
    default:
      return state;
  }
};
export default settingReducer;

combineReducers

: combineReducers의 역할은 모든 리듀서들을 한곳에 모아 객체로 만들 수 있는것이다. assign과 spread syntax처럼(같지는 않다.) 비슷하게 모아 주는 역할을 한다.

import { combineReducers } from "redux"; // 모듈 불러오기
import settingReducer from "./setting";  // 리듀서1
import videoReducer from "./video";	 // 리듀서2
import searchReducer from "./search";    // 리듀서3
//
export default combineReducers({  
  searchReducer,
  settingReducer,
  videoReducer,
});

Store(저장소)

: store 는 객체다.

store가 하는일

  • 애플리케이션의 상태를 저장한다
  • getState()를 통해 상태에 접근할 수 있게 해준다.
  • dispatch(action)를 통해 상태를 수정할 수 있게 한다.
  • subscribe(listener)를 통해 리스너를 등록한다.

사용법
: combineReducers()를 사용하여 모아둔 리듀서를 createStore(리듀서)로 스토어를 생성 할 수 있다. 두번째 인자도 존재하는데, 이 두번째 인자는 초기 상태를 지정해주고 싶을때 사용한다.

import { createStore } from 'redux'
import todoApp from './reducers'
//
let store = createStore(todoApp)

공식문서를 보면 어떻게 흘러가는지 work flow를 한눈에 볼 수 있는데 gif 파일이 있다. 꼭 참고 하자 !

container 와 presentational component 비교

container 와 presentational component의 차이점 자세히 보러가기

profile
UX를 개선하는것을 즐기고 새로운것을 배우는것을 좋아하는 개발자입니다.

0개의 댓글