React 상태관리와 Redux

seul·2022년 7월 6일
0

React

목록 보기
1/3
post-thumbnail

상태관리 도구의 필요성

  • 리액트에서 state는 컴포넌트 안에서 관리된다.
  • 자식 컴포넌트들 간의 state 직접 전달이 불가능하고, 최상위 부모 컴포넌트에 state를 배치하고 부모 컴포넌트로부터 state를 전달받아서 데이터를 전달해야 한다.
    • 문제점
    • 애플리케이션이 커서 관리하는 state가 많아질 경우 이 데이터 흐름이 복잡해진다.
    • 컴포넌트 구조가 바뀐다면 데이터 흐름을 완전히 바꿔야할 수도 있다.
    • 또한, 해당 state를 사용하지 않는데도 하위 컴포넌트에 전달하기 위해서 props를 내려받아야 한다. (props drilling이슈)
  • 이런 문제는 컴포넌트에서 상태변화 로직을 분리해서 전역상태를 관리할 수 있는 저장소를 따로 두고 관리하는 방식으로 해결할 수 있다.

Redux

  • Redux JavaScript의 라이브러리 중 하나(Node.js 모듈)이며, React와는 독립적인 존재
  • Redux는 MVC패턴을 대체하기 위한 아키텍처에 Reducer를 결합한 것

Redux의 세 가지 원칙

1. Single source of truth

  • 동일한 데이터는 항상 같은 곳에서 가지고 와야 한다
  • 데이터를 저장하는 Store라는 단 하나뿐인 공간이 있다.

2. State is read-only

  • Reducer 이외의 공간에서는 state는 읽기 전용
  • state를 변경시키는 유일한 방법을 Action 객체를 Reducer에 dispatch하는 것

3. Changes are made with pure functions

  • Reducer는 순수함수로 작성해야 한다.
  • parameter로 state, action을 전달받아서 기존의 state를 직접변경하는 것이 아니라, 새로운 state객체를 리턴해야 함

Redux의 구조

Redux에서는 Action → Dispatch → Reducer → Store 순서로 데이터가 단방향으로 흐른다.

  1. 상태가 변경되어야 하는 이벤트가 발생하면, 변경될 상태에 대한 정보가 담긴 Action 객체 생성
  2. Dispatch 함수의 인자로 Action객체를 전달
  3. Dispatch 함수는 Action 객체를 Reducer 함수로 전달
  4. Reducer 함수는 Action 객체의 값을 확인하고, 그 값에 따라 전역 상태 저장소 Store의 상태를 변경
  5. 상태가 변경되면, React는 화면을 다시 렌더링

Action

  • 어떤 액션을 취할 것인지 정의해 놓은 객체, type 필수, payload 옵션
{ type:ADD_TO_CART, payload: request }

Dispatch

  • Action을 전달하는 메서드
  • Action 객체를 전달받은 Dispatch 함수는 Reducer를 호출
// Action 객체를 직접 작성하는 경우
dispatch( { type: 'INCREASE' } );
dispatch( { type: 'SET_NUMBER', payload: 5 } );

// 액션 생성자(Action Creator)를 사용하는 경우
dispatch( increase() );
dispatch( setNumber(5) );

Store

  • state가 관리되는 오직 하나뿐인 저장소의 역할
import { createStore } from 'redux';

const store = createStore(rootReducer);

Reducer

  • Reducer는 현재의 state와 Action을 이용해서 새로운 state를 만들어 내는 순수함수
  • **dispatch에게 전달받은 action 객체의 type값에 따라서 상태를 변경시킴**
const count = 1

// Reducer를 생성할 때에는 초기 상태를 인자로 요구합니다.
const counterReducer = (state = count, action) {

  // Action 객체의 type 값에 따라 분기하는 switch 조건문입니다.
  switch (action.type)

    //action === 'INCREASE'일 경우
    case 'INCREASE':
			return state + 1

    // action === 'DECREASE'일 경우
    case 'DECREASE':
			return state - 1

    // action === 'SET_NUMBER'일 경우
    case 'SET_NUMBER':
			return action.payload

    // 해당 되는 경우가 없을 땐 기존 상태를 그대로 리턴
    default:
      return state;
}
// Reducer가 리턴하는 값이 새로운 상태가 됩니다.

Redux Hooks

useSelector()

  • 컴포넌트에서 useSelector 메서드를 통해 Store의 state에 접근할 수 있다. (컴포넌트와 state연결)
  • 전달인자로 콜백함수를 받고, 콜백함수의 전달인자로는 state 값이 들어감
// Redux Hooks 메서드는 'redux'가 아니라 'react-redux'에서 불러옵니다.
import { useSelector } from 'react-redux'
const counter = useSelector(state => state.counterReducer)
console.log(counter) // 1

useDispatch()

  • Action 객체를 Reducer로 전달해 주는 메서드
import { useDispatch } from 'react-redux'

const dispatch = useDispatch()
dispatch( increase() )
console.log(counter) // 2

dispatch( setNumber(5) )
console.log(counter) // 5

참고

profile
Connecting dots

0개의 댓글