Redux

Džeko.Log·2021년 5월 17일
0

Redux?

✏️ 애플리케이션에서 정교한 상태 관리를 구현하는 데 도움이되는 라이브러리 중 하나이다.

<장점>
1. 상태를 예측 가능하게 만들어준다
2. 유지보수
3. 디버깅에 유리하다 (Action과 state log 기록시)
4. 테스트를 붙이기 쉽다

Action

✏️ 상태 변화를 일으킬 때 참조하는 객체 (애플리케이션에서 저장소로 보내는 데이터 묶음), 자바스크립트 객체

  • 액션은 반드시 어떤 형태의 액션이 실행될지 나타내는 type 속성을 가져야 한다.
const ADD_TODO = 'ADD_TODO'
{
  type: ADD_TODO,   // 반드시 type이 존재 해야한다. 이 외는 자유
  text: 'Build my first Redux app'
}

// Action(액션) 생성자 => 액션을 만드는 함수 (액션과 액션 생성자는 다름)
function addTodo(text) {
  return {
    type: ADD_TODO,
    text: '리덕스 배우기'
  }
}

Reducer

✏️ 상태를 변화시키는 로직이 있는 함수이다, 현재 상태와 Action을 이용해 다음 상태를 만들어 냄

  • reducer는 액션(객체)를 받아서 새로운 state(객체)를 반환하는 역할을 한다.
  • reducer는 인자를 두개를 받는다 (이전 상태(previous state), 두번째인자는 액션(action))

<주의할 점>

  • 인수들을 변경해서는 안된다.
  • API호출이나 라우팅처럼 사이드 이펙트를 야기하는것들을 사용하면 안된다.
  • Date.now()나 Math.random() 같이 순수하지 않은 함수를 호출하면 안된다.
  • spread syntax나 assign을 사용하여 새로운 객체를 리턴해야한다.
function reducer(state, action) {
  // 상태 업데이트 로직
  return alteredState;
}

// counter를 위한 함수
function counter(state, action) {
  switch (action.type) {
    case 'INCREASE':
      return state + 1;
    case 'DECREASE':
      return state - 1;
    default:
      return state;
  }
}

Store

✏️ 애플리케이션의 상태 값들을 내장하고 있다 (저장소), 상태가 관리되는 오직 하나의 공간

<store가 하는일>

  • 애플리케이션의 상태를 저장한다
  • getState()를 통해 상태에 접근할 수 있게 해준다.
  • dispatch(action)를 통해 상태를 수정할 수 있게 한다.
  • subscribe(listener)를 통해 리스너를 등록한다.
import { createStore } from 'redux'
import todoApp from './reducers'
//
let store = createStore(todoApp)

Dispatch

✏️ Store의 내장함수 중 하나이며, 액션을 발생시키는 것 (액션을 파라미터로 전달 ⇒ dispatch(Action))

Subscribe

✏️ Store의 내장함수 중 하나이며, 함수 형태의 값을 파라미터로 받아옴

  • subscribe 함수에 특정 함수를 전달해주면, 액션이 디스패치 되었을 때 마다 전달해준 함수가 호출된다.

Redux의 3가지 원칙

1. Single Source of Truth

  • 단 하나의 store를 사용 (이 안에 모든 state값들이 포함)
  • 하나의 애플리케이션 안에는 하나의 스토어가 있다.
  • 스토어를 여러 개 생성해서 상태를 관리하면 안된다. 그 대신 리듀서를 여러 개를 만들어서 관리 할 수 있다.
  • 어플리케이션의 모든 상태는 하나의 저장소 안에 하나의 객체 트리 구조로 저장된다.

2. State is Read-only

  • 리덕스의 상태, state는 읽기 전용이다 (이 값은 절대로 직접 수정하면 안된다)
  • 상태를 업데이트 할 때는 언제나 새 상태 객체를 만들어서 넣어 주어야 한다 (concat, ...spread, Object .assign 등)
  • 리덕스에서 불변성을 유지해야 하는 이유? 내부적으로 데이터가 변경 되는 것을 감지하기 위하여 shallow equality 검사를 하기 때문. 이를 통하여 객체의 변화를 감지 할 때 객체의 깊숙한 안쪽까지 비교를 하는 것이 아니라 겉핥기 식으로 비교를 하여 좋은 성능을 유지할 수 있다.

3. Changes are made with pure functions

  • 리듀서 함수는 이전 상태와, 액션 객체를 파라미터로 받는다.
  • 이전의 상태는 절대로 건들이지 않고, 변화를 일으킨 새로운 상태 객체를 만들어서 반환한다.
  • 똑같은 파라미터로 호출된 리듀서 함수는 언제나 똑같은 결과값을 반환해야 한다.

Presentational 컴포넌트와 Container 컴포넌트의 개념

Presentational 컴포넌트 : 프리젠테이셔널 컴포넌트는 오직 뷰만을 담당하는 컴포넌트이다. 이 안에는 DOM 엘리먼트, 그리고 스타일을 갖고 있으며, 프리젠테이셔널 컴포넌트나 컨테이너 컴포넌트를 가지고 있을 수도 있다. 하지만, 리덕스의 스토어에는 직접적인 접근 권한이 없으며 오직 props 로만 데이터를 가져올수 있다. 또한, 대부분의 경우 state 를 갖고있지 않으며, 갖고있을 경우엔 데이터에 관련된것이 아니라 UI 에 관련된것이어야 한다.

주로 함수형 컴포넌트로 작성되며, state 를 갖고있어야하거나, 최적화를 위해 LifeCycle 이 필요해질때 클래스형 컴포넌트로 작성된다.

Container 컴포넌트 : 이 컴포넌트는 프리젠테이셔널 컴포넌트들과 컨테이너 컴포넌트들을 관리하는것을 담당한다. 주로 내부에 DOM 엘리먼트가 직접적으로 사용되는 경우는 없다. 사용되는 경우는 감싸는 용도일때만 사용 된다. 또한, 스타일을 가지고있지 않아야한다. 스타일들은 모두 프리젠테이셔널 컴포넌트에서 정의되어야 한다. 상태를 가지고 있을 때가 많으며, 리덕스에 직접적으로 접근 할 수 있다.

Redux hooks

  • useSelector() : 리덕스 스토어의 상태를 조회하는 Hook
  • useDispatch() : 리덕스 스토어의 dispatch 를 함수에서 사용 할 수 있게 해주는 Hook

0개의 댓글