요번 코드스테이츠에서의 블로깅 주제는 Redux의 데이터 흐름FLUX 패턴 에 대해 정리해보려합니다

 

  • Redux의 데이터 흐름
  • FLUX 패턴 

위의 흐름과 패턴에 앞서 redux를 사용해야하는 이유에대해 간략하게 적어보겠습니다.

Redux란?

리덕스 공식 홈페이지에선 리덕스의 설명을 다음의 사진과 같이 설명하고 있습니다.

  • Redux는 JavaScript 앱을 위한 예측 가능한 상태 컨테이너입니다.
  • Redux를 React또는 다른 라이브러리와 함께 사용할 수 있습니다

 

제가 생각하기에 리덕스를 사용하는 이유에대해 위의 사진을 가져와 봤습니다.

리덕스란 전역으로 상태를 관리하여 사용 및 관리를 도와주는 라이브러리라고 생각합니다 

위의 사진을 보고 왜 리덕스의 필요성이 있는지에대해 생각해봅시다

사용전

리액트에서 상태를 관리하기 위해서 useState를 사용합니다 

const [exampleNumber,setExampleNumber ] = useState(0)

useState 를 사용 시 현재 데이터가 관리되는 상태가 exampleNumber이며 useState( ) <- 괄호안의 값이 현재 상태에 값이 됩니다

exampleNumber 를 변경하려면 setExampleNumber 를 사용하여 현재  데이터가 관리되는 상태를 업데이트 시켜줘야합니다 

리덕스를 사용하기전에 위와 같은 상태관리를  1000개정도 되는 컴포넌트에서 사용한다고 가정을 해봅시다

최상단에서 현재 데이터가 관리되는 상태인 useState가 작성되어있고 제일밑에있는 컴포넌트에서 버튼을 클릭시 화면에 나오는 숫자가 바껴야한다면 

Props Drilling 현상이 일어납니다 

  • Props Drilling 은 props를 오로지 하위 컴포넌트로 전달하는 용도로만 쓰이는 컴포넌트들을 거치면서 React Component 트리의 한 부분에서 다른 부분으로 데이터를 전달하는 과정입니다.

Props Drilling은 적은 컴포넌트(1개 ~ 5 개)에서 사용 시 유지보수는 크게 어렵지않습니다

만약 1000개정도의 컴포넌트가 있다면 유지보수는 힘들게됩니다 

힘든이유에 대해 2가지로 나눠볼수있습니다

  1. 처음 컴포넌트 1에서 사용하고있는 useState를 마지막 컴포넌트 1000번째까지 props로 내려 상태를 관리해주어야한다면   현재상태인exampleNumber 와 현재 상태를 업데이트시켜주는 setExampleNumber 를  props로 전달해줘서 상태를 변화시켜줘야합니다
  2. 버튼 클릭 시 화면의 상태가 변화하려면 현재상태를 업데이트 시켜주는  setExampleNumber를 사용한 함수를 props로  전달되야합니다

위와 같이 2가지의 props로 1에서 1000번까지 간다면 유지보수가 힘들고 추적이 매우 불편합니다 

 

사용후

마찬가지로 상태를 관리해야하는 1000개정도의 컴포넌트가 있다고 생각해봅시다

리덕스를 사용한다면 사용전의 예와 다르게 동작합니다

사용전에는 상태관리를 위해 useState를 사용하고 이 상태를 첫번째 컴포넌트에서 관리하여 제일 밑의 컴포넌트로 props로  내려줬었습니다

리덕스를 사용한다면 특정 컴포넌트에 상태가 종속되지않아 상태 업데이트 관련 로직을 다른 파일로 분리시켜 전역으로 사용합니다 

전역으로 상태를 관리하고 있기 때문에 상태를 공유할때에 props drilling 이 일어나지않아 손쉽게 상태를 전달하거나 업데이트할수있습니다

규모가 큰 경우  체계적으로 관라할 수 있고, 코드의 유지 보수성을 높여주고 작업 효율을 극대화 시켜줍니다

리덕스는 미들웨어라는 기능을 제공하여 비동기 작업을 효율적으로 관리해줍니다

 

 

Redux의 데이터 흐름

Redux의 아키텍쳐는 엄격한 일방향 데이터 흐름을 따라 전개됩니다.

 

애플리케이션 내의 모든 데이터가 같은 생명주기 패턴을 따르며, 앱의 로직을 좀 더 예측가능하게 하고 이해하기 쉽게 만든다는 뜻입니다.

이는 또한 데이터 정규화를 도와서 같은 데이터의 복제본들이 서로를 모르는 여럿으로 나눠지고 말지 않도록 해줍니다.

 

Redux의 기본 구성

import { createStore } from 'redux'

//액션이 어떻게 상태를 다음 상태로 변경하는지 서술하는 함수인 리듀서
function reducer(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

//상태가 저장되는 공간인 스토어
let store = createStore(reducer)

//상태 변화를 감지하는 서브스크라이브
store.subscribe(() => console.log(store.getState())))

//내부 상태를 변경하는 유일한 방법인 액션과 그 액션을 리듀서로 보내줄 디스패치
store.dispatch({ type: 'INCREMENT' })// 1
store.dispatch({ type: 'DECREMENT' })// 0

store

리덕스에서 응용 프로그램의 상태 트리를 보유하는 객체입니다. 이 안에 현재 상태에 대한 데이터를 가지고 있고, 액션값을 받은 디스패치함수가 리듀서로 전달한 상태값을 여기에 저장합니다.

구독(subscribe)으로 상태가 업데이트 될 때 마다 다시 실행하게 해줍니다.

 

스토어는 단 1개의 상태값 만을 가질 수 있으며 객체 안에 여러가지 프로퍼티를 가질수있습니다

 

reducer

type Reducer<S, A> = (state: S, action: A) => S

리듀서는 액션의 type에 따라 변화를 일으키는 함수입니다.

스토어에 상태값이 들어가기전 액션값에서 전달된 'type'의 종류에 따라 어떤 상태값으로 스토어에 반환될지 정해줍니다.

리듀서 첫번째 파라미터에는 최초의 상태값이 무조건 정의되어야하며 두번째 파라미터엔 액션값을 넣어줍니다.

 

dispatch

 

디스패치 함수 (또는 단순히 디스패치 함수 )는 작업 또는 비동기 작업을 수락하는 함수 이며 스토어의 메서드이고 상태값 업데이트를 실행하는 함수입니다.

디스패치가 실행되면 파라미터로 전달받은 액션값이 리듀서의 두번째 파라미터 객체로 전달됩니다. 그러면 리듀서 안에있는 코드들로 인하여 스토어에 상태값이 저장됩니다.

 

action

디스패치의 파라미터로 전달될 데이터입니다.

액션은 상태값이 어떻게 변할지 행동을 적어놓은 객체입니다.

리듀서가 액션을 전달받으면 액션의 값에 따라서 다른 작업을 합니다.

액션은 무조건 객체여야하며  액션 객체에는 type 프로퍼티를 무조건 가지고 있어야합니다.

 

action creator

액션 객체를 생성해주는 함수입니다 

액션과 액션 크레에이터를 착각해서는 안됩니다

액션 생성자가 현재 상태를 읽어야 하거나 API 호출을 수행해야 하거나 라우팅 전환과 같은 부작용을 유발해야 하는 경우 액션 대신 비동기 액션을 반환해줘야 합니다 

 

Subscribe

스토어의 내장 함수 중 하나인 구독은 리스너 함수를 파라미터로 넣어 호출하면 상태가 업데이트될 때마다 호출되며 , 일종의 이벤트 리스너라고 볼 수 있습니다

 

Middleware

액션을 디스패치 했을때 리듀서에서 이를 처리하기에 앞서 사전에 지정된 작업들을 실행한다.

종종 비동기작업을 작업으로 바꿉니다

 

이미지 출처 : https://velog.io/@annahyr/%EB%A6%AC%EB%8D%95%EC%8A%A4-%ED%9D%90%EB%A6%84-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0

 

리덕스 흐름 이해하기

리덕스는 가장 많이 사용하는 리액트 상태 관리 라이브러리입니다. 리덕스를 사용하면 컴포넌트의 상태 업데이트 관련 로직을 다른 파일로 분리시켜서 더욱 효율적으로 관리할 수 있다. 또한,

velog.io

Flux 패턴

facebook 은 Flux 패턴을 만들게 되었으며 만든 이유는 대규모 어플리케이션에서 보다 일관된 데이터 관리를 하기 위해서였습니다.

Flux 애플리케이션은 디스패처, 스토어, 뷰(React 구성 요소)의 세 가지 주요 부분으로 구성됩니다.

 

기존의 어플리케이션 환경에서 보편적으로 사용되는 패턴은 MVC였습니다.

Model에 데이터를 정의해 두고, Controller를 이용해 Model 데이터를 생성 / 조회 / 수정 / 삭제(CRUD)하고, 변경된 데이터는 View에 출력되면서 사용자에게 전달됩니다.

MVC 패턴이란?

MVC란 Model-View-Controller의 약자로 애플리케이션을 세 가지 역할로 구분한 개발 방법론입니다.

이 패턴의 문제점은 어플리케이션의 규모가 커질수록 데이터 흐름의 복잡도가 무지막지하게 늘어난다는 것이었습니다.

MVC 패턴은 데이터의 변경 사항을 신속하게 전파하기가 어렵고 모델이 늘어날수록 전파해야 할 대상도 함께 늘어나 문제가 발생됩니다

이러한 문제가 어플리케이션 전체적으로 무차별적으로 어떤 변화가 일어날지 예측할 수가 없다는 데에 있습니다

 

 

facebook은 이 문제를 해결하기 위해 flux라는 패턴을 만들었습니다

이 흐름은 Model이 View를 반영하고, View가 Model을 변경하는 양방향 데이터 흐름에서 벗어나 단방향으로만 데이터를 변경할 수 있도록 만들었습니다

 

단방향 데이터 흐름에 대해 알아봅시다

 

Action / Action Creator

 

액션은 데이터의 상태를 변경할 수 있는 명령어 카드와 같습니다.

액션 생성자는 새로 발생한 액션의 타입과 데이터 페이로드를 액션 메시지로 묶어 디스패쳐로 전달합니다.

 

Dispatcher

 

디스패쳐는 액션 메시지를 감지하는 순간 그것을 각 스토어에 전달합니다.

전달은 콜백 함수로 이루어지며, 등록되어 있는 모든 스토어로 페이로드를 전달할 수 있습니다.

이때 스토어가 서로를 의존하고 있다면 특정 스토어가 업데이트되기를 기다리게 해주는 waitFor()를 사용할 수 있습니다.

 

Store (Model)

 

스토어는 어플리케이션의 상태와, 상태를 변경할 수 있는 메서드를 가지고 있습니다.

어떤 타입의 액션이 날아왔느냐에 따라 메서드를 다르게 적용해 상태를 변경하게 됩니다.

 

View

 

React ( 클라이언트 )에 해당되는 부분입니다.

컨트롤러 뷰는 스토어에서 변경된 데이터를 가져와 모든 자식 뷰에게 데이터를 분배합니다. 데이터를 넘겨받은 뷰는 화면을 새로 렌더링합니다.

+ Recent posts