[Redux] Redux에 대하여

jwp9633·2022년 9월 1일
0

서론

리액트에서 데이터는 위에서 아래로 흐르는 방식을 채택하였다. 리액트는 state와 props를 활용하여 데이터를 관리한다.

한 컴포넌트 내에서 사용자의 상호작용에 의해 변하는 데이터는 state로 관리하고, 상위 컴포넌트의 데이터를 변경하지 않을 때에는 props로 데이터를 전달 받아 이용한다. 하위 컴포넌트에서 상위 컴포넌트의 state를 변경해야 할 때는 상위 컴포넌트에서 state를 변경하는 함수를 props로 하위 컴포넌트로 전달하고, 하위 컴포넌트에서 그 함수를 실행하는 방식을 채택한다.

만약 한 데이터가 여러 개의 컴포넌트에서 사용되고 변경된다면, 최상위 컴포넌트로 state를 끌어올리고, 그 데이터(필요하다면 데이터를 변경하는 함수까지)를 props로 컴포넌트에 전달한다. 이를 '상태 끌어올리기'라고 한다.

리액트는 상태 끌어올리기를 통해 single source of truth(같은 데이터는 항상 같은 곳에서 가져와야 한다) 규칙을 지키고 있었다. 그러나 같은 데이터를 사용하는 컴포넌트가 많고, 최상위 컴포넌트와 데이터를 사용하는 컴포넌트 간의 거리가 멀다면(중간에 많은 컴포넌트가 끼어있다면) props drilling이 발생한다.

props drilling은 상위 컴포넌트의 state를 props로 전달하기 위해 단순히 전달 목적으로 여러 컴포넌트를 거치는 현상을 말한다. props drilling은 코드의 가독성을 떨어뜨리고, 유지보수가 어려워지며, 불필요한 리렌더링이 발생하는 문제가 있다.

따라서 props drilling의 문제점을 해결하기 위해 상태 관리 라이브러리가 등장하게 되었다. 상태 관리 라이브러리는 state를 전역으로 관리하는 저장소를 만들고, state가 필요할 때마다 저장소에서 꺼내 쓰는 방식으로 props drilling을 해결하였다.

상태 관리 라이브러리에는 Redux, MobX, Recoil 등 많은 도구가 존재하는데, 2022년 기준 가장 많이 사용되고 있는 Redux에 대해 자세히 알아보자.

Redux

Redux 공식문서에 따르면, 리덕스는 크게 4가지 특징을 가지고 있다.

예측가능성

리덕스는 애플리케이션을 작성할 때, 다양한 환경에서 항상 일관적으로 작동하도록 도와준다.
또한, 애플리케이션을 테스트하기 용이하다.

중앙화

애플리케이션의 상태와 로직을 중앙화하여 undo/redo, 상태 지속성 등과 같은 강력한 기능을 가능하게 한다.

유지보수성

애플리케이션의 상태가 변화했을 때 이를 추적하기 쉽다. 리덕스 아키텍져는 변화를 로깅하여 오류 리포트를 서버로 전송할 수 있다.

유연성

리덕스는 어떤 UI 계층과도 함께 사용할 수 있다.

Redux의 데이터 흐름

Action -> Dispatch -> Reducer -> Store

리덕스는 상태를 변경해야 하는 상황이 발생하면 다음의 흐름을 따른다.

  1. 상태 변경에 대한 정보가 담긴 Action 객체를 생성한다.
  2. Action 객체를 Dispatch 함수의 인자로 전달한다.
  3. Dispatch 함수는 Action 객체를 Reducer 함수로 전달한다.
  4. Reducer는 Action 객체의 정보에 따라 Store에 담겨 있는 상태를 변경한다.
  5. 화면을 다시 렌더링한다.

Action

Action 객체에는 행동(type)과 payload가 담겨 있다. payload는 필요 없다면 생략한다.

// payload가 필요 없는 경우
{ type: 'PLUS_ONE' }

// payload가 필요한 경우
{ type: 'PLUS', payload: 3 }

Dispatch

Dispatch는 Action 객체를 Reducer로 전달하는 함수이다. Dispatch 함수의 전달인자는 Action 객체이다.

dispatch({ type: 'PLUS_ONE' });
dispatch({ type: 'PLUS', payload: 3 });

Reducer

Reducer는 Dispatch한테 전달받은 Action 객체의 type에 따라 상태를 변경하는 함수이다.

const plusReducer = (state = 0, action) => {
  switch (action.type) {
    case 'PLUS_ONE':
      return state + 1;
    case 'PLUS':
      return state + action.payload;
    default:
      return state;
  }
};

Store

Store는 state가 저장되어 있는 공간이다.

import { configureStore } from '@reduxjs/toolkit'

export default configureStore({
  reducer: {}
})

참고문헌

profile
JUST DO IT.

0개의 댓글