[React] 상태관리 | Redux

Eunji Lee·2022년 12월 28일
0

[TIL] Front-end

목록 보기
25/36
post-thumbnail

Redux 알아보기

의미

  • 자바스크립트 앱을 위한 예측 가능한 상태 관리 라이브러리
  • action이라는 이벤트를 사용해서 애플리케이션의 상태를 관리하고 업데이트하는 라이브러리
  • 애플리케이션의 전역 상태를 store에 저장하고, 이러한 state는 예측가능한 방식으로만 업데이트 됨

⚠️ React 없이도 사용할 수 있는 상태 관리 라이브러리임

필요성

Redux와 React 비교

ReduxReact
컴포넌트와 상태를 분리하는 패턴상태와 속성(props)을 이용한 컴포넌트 단위 개발 아키텍처
  • React의 경우, 컴포넌트와 상태가 분리되어 있지 않아 컴포넌트 안에서 상태 변경 로직이 복잡하게 얽혀있는 경우 존재할 수 있음
  • 반면, Redux의 경우, 상태 변경 로직을 컴포넌트로부터 분리하기 때문에 보다 단순한 함수 컴포넌트로 만들 수 있음

Redux의 세 가지 원칙

1. Single source of truth

  • 애플리케이션의 모든 상태는 하나의 저장소 안에 하나의 객체 트리 구조로 저장됨
  • 애플리케이션의 전역 상태를 보관하는 공간인 Store 와 연결되는 개념

2. State is read-only

  • 상태는 읽기 전용이라는 뜻으로, Redux의 상태를 직접 변경할 수 없음
  • Action 객체를 전달하는 것이 상태를 변화시키는 유일한 방법임

3. Changes are made with pure functions

  • 액션에 의해 상태 트리가 어떻게 변화할 것인지 지정하는 일은 순수함수로만 가능
  • 상태가 엉뚱한 값으로 변경되는 일이 없도록 순수함수로 작성되어야하는 Reducer와 관련 있음



상태 관리 과정

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

즉, Redux에서는 데이터가 단방향으로 흐르며, 그 순서는 Action → Dispatch → Reducer → Store




주요 개념

Store

의미

  • 상태가 관리되는, 오직 하나뿐인 저장소
  • Redux 앱의 state가 저장되어 있는 공간

적용하기

createStore메서드를 활용해 Reducer를 연결해서 Store를 생성
⚠️ 반드시 Reducer와 연결해야함

import { createStore } from 'redux';

const store = createStore(rootReducer);

Reducer

의미

  • Dispatch에게서 전달받은 Action 객체의 type값에 따라서 상태를 변경시키는 함수
  • Reducer순수함수
    → 외부 요인과 관계없이 기대한 값으로만 상태가 변경되게 하기 위해

적용하기

  • Root Reducer 만들기
    • createStore에 전달할 reducer
    • 현재 stateaction을 전달인자로 받아 새로운 state를 리턴함
      → 즉, (state, action) => newState
    • 예시: count를 증가 또는 감소시킬 때
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가 리턴하는 값이 새로운 상태가 됩니다.
  • 여러 개의 Reducer를 사용하는 경우
    • combineReducers메서드를 사용해서 하나의 Reducer로 합치기
import { combineReducers } from 'redux';

const rootReducer = combineReducers({
  counterReducer,
  anyReducer,
  ...
});

Action

의미

어떤 액션을 취할 것인지 정의해 놓은 객체

적용하기

Action의 요소

  • type
    • 필수로 지정
    • 해당 Action 객체가 어떤 동작을 하는지 명시해주는 역할
    • 대문자와 Snake Case로 작성
  • payload
    • optional: 구체적인 값을 전달하고 싶을 때

액션 생성자(Action Creator)

보통 Action 객체를 생성하는 함수를 만들어 사용

// payload가 필요 없는 경우
const increase = () => {
  return {
    type: 'INCREASE'
  }
}

// payload가 필요한 경우
const setNumber = (num) => {
  return {
    type: 'SET_NUMBER',
    payload: num
  }
}

Dispatch

의미

  • Reducer로 Action을 전달해주는 함수
  • Dispatch의 전달인자로 Action 객체가 전달
  • Action 객체를 전달받은 Dispatch 함수는 Reducer를 호출

적용하기

// Action 객체를 직접 작성하는 경우
dispatch( { type: 'INCREASE' } );
dispatch( { type: 'SET_NUMBER', payload: 5 } );

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



Redux Hooks

  • React-Redux에서 Redux를 사용할 때 활용할 수 있는 Hooks 메서드
  • Redux Hooks 메서드는 'redux'가 아니라 'react-redux'에서 불러오기

useDispatch()

Dispatch 함수를 반환하는 메서드

import { useDispatch } from 'react-redux'

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

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

useSelector()

컴포넌트와 state를 연결하여 Redux의 state에 접근할 수 있게 해주는 메서드

import { useSelector } from 'react-redux'
const counter = useSelector(state => state)
console.log(counter) // 1

참고자료
ko.redux.js.org

0개의 댓글