Redux의 데이터 흐름

쉐런·2022년 9월 5일
1

JAVASCRIPT

목록 보기
4/5

Redux란?

Redux는 애플리케이션에서 정교한 상태 관리를 구현하는 데 도움이 되는 라이브러리 중 하나이다.
즉, 상태 관리 라이브러리라고 할 수 있다.
Redux는 컴포넌트와 상태를 분리하는 패턴을 써서 상태 관리를 편하게 도와주는 도구이다.

!종종 Redux는 React의 관련 라이브러리 혹은 하위 라이브러리라는 오해가 있는데 전혀 그렇지 않으며 다른 라이브러리와 프레임워크도 Redux의 개념을 많이 채택했음을 알아두자!

Redux가 JavaScript 커뮤니티에서 인기가 왜 많아요?

과거에 JavaScrip의 모든 것을 지배하는 jQuery 라이브러리가 있었다.

DOM을 조작하고 애니메이션을 보고 재사용 가능한 위젯을 구현하는데 주로 사용되었고
JavaScript에서 최고의 라이브러리였다.

그러나 jQuery의 사용이 급증하고 애플리케이션 크기가 커지면서 JavaScript 코드의 크기도 커졌고 악명 높은 스파게티 코드로 코드가 엉망이 되기 시작했다.

그렇게 1세대 프레임워크 라이브러리가 등장하여 인기를 얻다가 Facebook에서 출시한 React가 출시되었는데 2세대 SPA 솔루션 중 하나 였다.

React에서는 단방향 데이터 흐름의 원칙이 대중화되었으나 상태 관리 문제에 계속 부딪히면서
Facebook이 Flux 패턴을 도입하게 되었다.

Flux 패턴?

Flux는 상태 관리 문제를 해결하기 위해 Facebook이 만들었으며 Model이 View를 반영하고 View가 Model를 반영했던 양방향 데이터 흐름에서 벗어나 단방향으로만 데이터를 변경할 수 있도록 만들었다.

React의 구성 가능한 뷰 구성 요소를 보완하며 프레임 워크라기보다는 패턴에 가깝고 많은 새 코드 없이 Flux를 즉시 사용 할 수 있다.

Redux는 Flux 패턴의 후속 라이브러리가 되었다.
Redux라는 단어도 Reducer과 Flux라는 두 단어를 결합한 것이다.

Redux와 Flux 패턴

밑에 양방향 데이터 흐름을 해결 하기 위해서

이렇게 단방향 데이터 흐름으로 바꾼 Flux 패턴!

Redux는 이 Flux 패턴에서 몇 가지 제약 조건을 채택했으나 전부는 아니다.

Redux는 다음과 같은 순서로 상태를 관리!

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

⇒ 즉, Redux에서는 Action → Dispatch → Reducer → Store 순서로 데이터가 단방향으로 흐름!

1. Store (전역 상태 저장소) 설정

  • Store는 상태가 관리되는 오직 하나뿐인 저장소의 역할!
    • Redux 앱의 state가 저장되어 있는 공간
  • 아래 코드와 같이 createStore 메서드를 활용해 Reducer를 연결해서 Store를 생성할 수 있다.
import {createStore} from 'redux';
// createStore 인자에 reducer를 연결해줌
const store = createStore(rootReducer);

2. Reducer

Redux는 Reducer과 Flux라는 두 단어를 결합한 것이다.

  • Reducer는 Dispatch에게서 전달받은 Action 객체의 type 값에 따라서 상태를 변경시키는 함수
  • 이 때, Reducer는 순수함수여야 한다!
    • 외부 요인으로 인해 기대한 값이 아닌 엉뚱한 값으로 상태가 변경되는 일이 없어야 하기 때문!
const count = 1 // default value! 

const counterReducer = (state = count, action) => {
	// Action 객체의 type 값에 따라 분기하는 switch 조건문
  • Reducer함수 첫번째 인자에는 기존 state가 들어오게 된다.
    - 첫번째 인자에는 default value를 꼭 설정해주기! (ex. const count = 1)
    - 그렇지 않을 경우, undefined가 할당되기 때문에 그로 인한 오류가 발생할 수 있다.
  • 만약 여러 개의 reducer를 사용하는 경우
    • Redux의 combineReducers 메서드를 사용해서 하나의 Reducer로 합쳐줄 수 있음
    • 객체 안에다가 넣어주기
import {combineReducers} from 'redux';

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

3. Action

Action은 말 그대로 어떤 액션을 취할 것인지 정의해 놓은 객체로, 다음과 같은 형식으로 구성됨

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

// payload가 필요한 경우
{type: 'SET_NUMBER', payload: 5}
  • 여기서 type은 필수로 지정을 해 주어야 함!
    • 해당 Action 객체가 어떤 동작을 하는지 명시해주는 역할
    • 대문자와 Snake Case로 작성한다!(like MY_BLOG)
    • 여기에 필요에 따라 payload를 작성해 구체적인 값을 전달!
  • 보통 Action을 직접 작성하기보다는 Action 객체를 생성하는 함수를 만들어 사용하는 경우가 많음! ⇒ 이러한 함수를 액션 생성자 (Action Creator) 라고도 함
//payload가 필요 없는 경우
// payload가 필요 없는 경우
const increase = () => {
	return {
		type : "INCREASE"
	}
}
// payload가 필요한 경우
const setNumber = (num) => {
  return {
    type: 'SET_NUMBER',
    payload: num
  }
}

4. Dispatch

  • Dispatch는 Reducer로 Action 객체를 전달해주는 함수
  • Dispatch의 전달인자로 Action 객체가 전달 됨
//dispatch 인자로 Action 객체를 직접 작성하는 경우
dispatch ( {type: 'INCREASE'});
dispatch({type: 'SET_NUMBER', payload: 5});

//dispatch 인자로 액션 생성자(Action Creator, 함수)를 사용하는 경우
const increase = () => {
	return {
		type : "INCREASE"
	}
}
dispatch(increase());
dispatch(setNumber(5));

Redux Hooks

위에 나온 1번~4번을 연결해보자

  • React-Redux에서 Redux를 사용할 때 활용할 수 있는 HOOKs 메서드를 제공!
    - 그 중에서 크게 useSelector(), useDispatch() 이 두 가지 메서드를 기억하기

useDispatch()

  • useDispatch()는 Action 객체를 Reducer에 전달해주는 Dispatch함수를 반환하는 메서드
    • dispatch의 인자로 action객체를 넣어준다!
import {useDispatch} from 'react-redux'

const dispatch = useDispatch()
//dispatch의 인자로 action객체를 넣어준다! 
dispatch( increase() )
console.log(counter) // 2

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

useSelector()

  • useSelector()는 컴포넌트와 state를 연결하여 Redux의 state에 접근할 수 있게 하는 메서드
//Redux Hooks 메서드는 'redux'가 아니라 'react-redux'에서 불러옴
import {useSelector} from 'react-redux'

const counter = useSelector(state => state)
console.log(counter) //1 

Redux의 세가지 원칙

각각의 원칙이 Redux의 어떤 구성 요소와 연결이 되는지 확인해보기

1. Single source of truth

동일한 데이터는 항상 같은 곳에서 가지고 와야 한다는 의미입니다. 즉, Redux에는 데이터를 저장하는 Store라는 단 하나뿐인 공간이 있음과 연결이 되는 원칙입니다.

2. State is read-only

상태는 읽기 전용이라는 뜻으로, React에서 상태갱신함수로만 상태를 변경할 수 있었던 것처럼, Redux의 상태도 직접 변경할 수 없음을 의미합니다. 즉, Action 객체가 있어야만 상태를 변경할 수 있음과 연결되는 원칙입니다.

3. Changes are made with pure functions

변경은 순수함수로만 가능하다는 뜻으로, 상태가 엉뚱한 값으로 변경되는 일이 없도록 순수함수로 작성되어야하는 Reducer와 연결되는 원칙입니다.

profile
How?

0개의 댓글