React Redux

Redux 란?

가장 사용률이 높은 상태관리 라이브러리입니다.
리덕스를 사용하면, 우리가 만들게 될 컴포넌트들의 상태 관련 로직들을
다른 파일들로 분리시켜서 더욱 효율적으로 관리 할 수 있습니다.
또한, 컴포넌트끼리 상태를 공유하게 될 때
여러 컴포넌트를 거치지 않고도 손쉽게 상태 값을 전달 할 수 있습니다.
추가적으로, 리덕스의 미들웨어라는 기능을 통하여 비동기 작업, 로깅 등의
확장적인 작업들을 더욱 쉽게 할 수도 있게 해줍니다.

React 컴포넌트 와 Redux 차이점

React 에서 아래와같이 데이터 전달을 해야할때 
기본적인 parent-child 구조 로 전달됩니다.

react

위 문제를 해결하기 위해서 FLUX 라는 디자인 패턴이 만들어졌습니다.
시스템에서 어떠한 Action 을 받았을 때, Dispatcher가 받은 Action들을 통제하여 
Store에 있는 데이터를 업데이트합니다. 그리고 변동된 데이터가 있으면 View 에 리렌더링합니다.
그리고, View에서 Dispatcher로 Action을 보낼 수도 있습니다.
아래는 Redux의 데이터 교류 구조

redux

위와 같이, store에서 모든 데이터를 담고 있고, 
컴포넌트 끼리는 직접 교류하지 않고 store 중간자를 통하여 교류합니다. 
빨간 화살표는 dispatch 를 의미하며 store에 있는 데이터를 업데이트 하는것을 가르키고, 
주황색 화살표는 subscribe를 의미하며, 해당 컴포넌트에서 store에 있는 특정 데이터의 
변동을 주의하고있다가 변동이 있을시 바로 반영시키는것을 가르킵니다.

React에서 Redux필요성

REACT 는 부모 component > 자식 component 의 단방향 데이터 전달 방식을 사용합니다.
또한 전역변수가 존재하지 않습니다. 
물론 callback 함수를 만들어 부모에게 전달할수는 있으나 개발시 피로도가 높고 자유도 또한 제한됩니다.

때문에 리덕스는 글로벌 상태 관리를 하게 될 때 굉장히 효과적입니다. 
물론, React 에서 공식 지원하는 Context API 를 통해서도 동일한 작업을 할수는 있으나,
이 대중적으로 많이 사용하는 Redux 에대하서 설명하도록 하겠습니다. 

Redux 기본용어

store : 애플리케이션의 상태 값들을 내장하고 있다
action : 상태변화를 일으킬 때 참조하는 객체
dispatch : 액션을 스토어에 전달하는 것을 의미
reducer : 상태를 변화시키는 로직이 있는 함수
subscribe : 스토어 값이 필요한 컴포넌트는 스토어를 구독

REACT JS + REDUX 적용하기

웹(HTML)에서 redux 사용은 불가능 합니다.
Redux 는 export 와 import 를 통해 component와 데이터 교류 (connect) 를 하는데
export 문을 HTML 내장 스크립트에 사용할 수는 없습니다. (.js 또는 .msj에서만 사용가능)
때문에 node js 를 이용한 적용방법을 설명드리겠습니다.
-- 프로젝트생성
create-react-app my-app
cd my-app 

--리덕스 모듈 설치
npm install redux
npm install react-redux

--리덕스 미들웨어 설치 (thunk)
npm install --save redux-thunk

--실행
npm start

소스 : Click!

REDUX Middleware

redux-middleware

미들웨어는, 액션이 디스패치(dispatch) 되어서 리듀서에서 이를 처리하기전에 
사전에 지정된 작업들을 설정합니다. 
미들웨어를 액션과 리듀서 사이의 중간자라고 이해하시면 되겠습니다.
리듀서가 액션을 처리하기전에, 미들웨어가 할 수있는 작업들은 여러가지가 있는데요. 
단순히 전달받은 액션을 콘솔에 기록을 할 수도 있고, 전달받은 액션에 기반하여 
액션을 아예 취소시켜버리거나,  다른 종류의 액션들을 추가적으로 디스패치 할 수도 있습니다.

redux-thuk

리덕스를 사용하는 어플리케이션에서 비동기 작업을 처리 할 때 가장 기본적인 
방법으로는 redux-thunk 라는 미들웨어를 사용하는것입니다.
redux 공식 매뉴얼에서도 이 미들웨어를 사용하여 비동기 작업을 다룹니다. 
이를 사용하여 비동기 작업을 관리하는건 매우 직관적이고 간단합니다.
thunk란, 특정 작업을 나중에 하도록 미루기 위해서 함수형태로 감싼것을 칭합니다.
예를 들어서 여러분들이 1 + 1 을 지금 당장 하고싶다면 이렇게 하겠죠?

const x = 1 + 2;

이 코드가 실행되면 1 + 2 의 연산이 바로 진행됩니다.
하지만 다음과 같이 하면 어떨까요?

const foo = () => 1 + 2;

이렇게 하면, 1 + 2 의 연산이 코드가 실행 될 때 바로 이뤄지지 않고 
나중에 foo() 가 호출 되어야만 이뤄집니다.
가장 간단히 설명하자면, 이 미들웨어는 객체 대신 함수를 생성하는 
액션 생성함수를 작성 할 수 있게 해줍니다. 
리덕스에서는 기본적으로는 액션 객체를 디스패치합니다. 
일반 액션 생성자는, 다음과 같이 파라미터를 가지고 액션 객체를 생성하는 작업만합니다:

const actionCreator = (payload) => ({action: 'ACTION', payload});

만약에 특정 액션이 몇초뒤에 실행되게 하거나, 현재 상태에 따라 아예 액션이 무시되게 하려면, 
일반 액션 생성자로는 할 수가 없습니다. 하지만, redux-thunk 는 이를 가능케합니다.
우선 1초뒤 액션이 디스패치되게 하는 예제코드를 살펴보겠습니다:

const INCREMENT_COUNTER = 'INCREMENT_COUNTER';

function increment() {
    return {
        type: INCREMENT_COUNTER
    };
}

function incrementAsync() {
    return dispatch => { // dispatch 를 파라미터로 가지는 함수를 리턴합니다.
        setTimeout(() => {
        // 1 초뒤 dispatch 합니다
        dispatch(increment());
        }, 1000);
    };
}

참고 : redux devTool (https://thomasdavis.github.io/react-redux-tutorials/)

카테고리 > techCamp