본문 바로가기
  • AI (Artificial Intelligence)
Programming/JavaScript, Node.js

리덕스(Redux)를 왜 사용하는가?

by 로샤스 2021. 7. 12.

Ref. https://medium.com/@jsh901220/react%EC%97%90-redux-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0-a8e6efd745c9

리덕스(Redux)란?

리덕스(Redux)는 Javascript app을 위한 예측가능한(predictable) state container이다. 리액트 뿐만 아니라 Augular, jQuery, vanilla JavaScript 등 다양한 framework와 작동되게 설계되었다. 즉, 리액트만을 위한 Library는 아니다.

react, jquery, ember… 다양한 곳에적용 가능. redux만을 사용할 수도 있다.

리덕스는 리액트의 멋진 보완재이다. action에 반응하여 상태를 변경하기 때문에, 액트 같이 UI를 상태에 대한 함수로 기술하는 프레임워크와 특히 잘 어울리기 때문이다.

React에 리덕스(Redux)가 필요한 이유?

리액트로 프로젝트를 진행하게 되면, Component는 local state를 가지게 되고, 어플리케이션은 global state를 가지게 된다.

local state: 각각의 Component가 가지는 state. 어플리케이션은 이 state를 기반으로 만들어진다.
global state: 예를 들어, 유저의 로그인의 유무에 따라 어플리케이션의 state가 달리 보이는 것을 들 수 있다. 어플리케이션 전체에서 global state는 유지, 즉 local state는 global state를 공유하게 되는 것이다.

리액트로만 프로젝트를 진행하게 될 경우 우리의 어플리케이션은 local state, 그리고 global state를 관리하기 어렵다. 이 때 생기는 몇가지 문제를 가지고 왜 리덕스가 필요한지 설명해보도록 하겠다. 예제는 전에 진행하였던 Simple React Shopping Mall 만들기 프로젝트를 참조하겠다.

. local state의 전달이 어렵다: shopping mall 프로젝트 에서는 장바구니를 관리하기 위해 최상단 Component인 App.js에서 cart state를 만들고, 각각의 Component에 이를 props로 전달하여 프로젝트를 관리했었다.

short!

프로젝트의 구조가 굉장히 단순하였기 때문에 단 한번의 data이동으로 cart state가 전달되었다. 하지만, 프로젝트의 규모가 커지고 Component의 수가 늘어나게 된다면 어떻게 될까?

long…

나는 단순히 cart state를 CartItem.js로 전달하고 싶은데, 이를 위해 cart props를 사용하지 않는 Component에도 cart props를 전달하게 된다. 프로젝트의 규모가 커질수록, props로 data를 전달하기 위해 이렇게 필요없는 data의 흐름이 생기게 된다. 또한, 만약 CartItem.js에서 제대로 cart props가 전달이 안 될 경우, 중간에 끼인 모든 Component에서 일일이 문제점을 찾아봐야 한다.

. global state의 유지가 어렵다: shopping mall을 포함한 대부분 어플리케이션에서는 로그인 기능이 구현되어야 한다. 유저마다의 개인정보, 그리고 결제정보 등이 있어야 되기 때문이다. 하지만 리액트만으로 프로젝트를 진행하면, global state를 모든 Component에 유지하기 어렵다. 유저의 인증정보를 모든 Component에 props로 계속해서 전달해야 하는데, 상단의 diagram보다 훨씬 복잡한 절차를 거치게 될 것이다.

use redux

하지만 리덕스를 사용하게 되면 하나의 store를 통해 global state을 포함한 모든 state를 저장, 유지할 수 있게 되며, 원하는 Component로만 data를 전달할 수 있게 되어 이러한 문제가 해결된다.

Flux 구조

Flux는 Facebook에서 만든 client-side web applications을 구축할 때 사용하는 application architecture(앱 구조), design pattern(디자인 패턴)이다. MVC (Model–View–Controlle)구조 의 단점을 보완할 목적으로 개발된 Flux는 대규모 프로젝트에서 너무 복잡해지는 MVC구조의 단점을 보완하는 단방향 데이터 흐름(unidirectional data flow)의 구조이다.

mvc vs flux

Flux에 대해 간략히 소개하는 이유는, 우리가 앞으로 살펴보아야 할 리덕스가 Flux의 구현체라고 할 수도 있기 때문이다.

— 관련 링크

flux vs redux

리덕스는 Flux의 몇 가지 중요한 특성에 영감을 받아 개발되었다. Flux와 달리 리덕스는 dispatcher라는 개념이 존재하지 않는다. 그리고 다수의 store도 존재하지 않는다. 대신 리덕스는 하나의 root에 하나의 store만이 존재하고, 순수함수(pure functions)에 의존하는데, 이 순수 함수는 이것들을 관리하는 추가적인 entity 없이도 조합하기 쉽다 .

물론 차이점이 있지만, 결론적으로 Flux, 리덕스 두 가지의 구조 모두 닮았으며 결국 리덕스는 Flux 패턴을 좀 더 쉽고 정돈된 형태로 쓸 수 있게 도와주는 라이브러리라고 볼 수 있다. 서로 영향을 많이 주고받았기 때문에 리덕스를 공부할 때 Flux구조를 공부하는 것은 많은 도움이 될 것이다.

Redux 기본 개념

. Actions(액션): 어플리케이션의 store(스토어), 즉 저장소로 data를 보내는 방법이다. view에서 정의되어있는 액션을 호출하면 action creators(액션 생성자)는 어플리케이션의 state(상태)를 변경하여 준다. 공식문서에 나와있는 예제를 살펴보자.

const ADD_TODO = 'ADD_TODO' // action의 type을 정의

action의 type은 일반적으로 문자열 상수로 정의된다. 정의된 action type은 action creators(액션 생성자)를 통해 사용된다.

function addTodo(text) {
return {
type: ADD_TODO,
text
}
}

. Reducers(리듀서): action을 통해 어떠한 행동을 정의했다면, 그 결과 어플리케이션의 상태가 어떻게 바뀌는지는 특정하게 되는 함수이다.

function todoApp(state = initialState, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return Object.assign({}, state, {
visibilityFilter: action.filter
});
default:
return state
}
}

리듀서 함수에서는 action의 type에 따라 변화된 state를 반환하게 된다.

. Store(스토어): “무엇이 일어날지”를 나타내는 action, 그리고 action에 따라 상태를 수정하는 reducer를 저장하는 어플리케이션에 있는 단 하나의 객체이다.

import { createStore } from 'redux';
import todoApp from './reducers';

let store = createStore(todoApp);

이처럼 store을 생성하고 reducer을 연결하여 어플리케이션에 연결하게 된다.

다음 블로그에서는 실제로 프로젝트에 redux를 적용해보겠다.

'Programming > JavaScript, Node.js' 카테고리의 다른 글

Migrating from npm  (0) 2021.07.12
[sequelize] 컬럼 정의  (0) 2021.07.06
[Sequelize] Data type of Model in Sequelize  (1) 2021.07.06
[sequelize] DATETIME to TIMESTAMP  (1) 2021.07.06
serverless-dotenv-plugin  (0) 2021.06.30

댓글