리액트는 사용자 정의 컴포넌트를 만들어서 코드를 간결하게 정리정돈할 수 있게 해주고,

리덕스는 데이터를 중앙에서 관리하여 데이터가 예기치 않게 변하는 것을 방지해준다.

 

출처 - https://www.slideshare.net/binhgdgmail/006-react-redux-framework

위 그림은 리액트와 리덕스를 단독으로 사용했을 때 데이터의 흐름을 보여준다.

리액트는 어떤 컴포넌트에서 데이터가 변화되면 그 정보가 다른 컴포넌트들에게 전파된다. 이 때 그 데이터를 사용할 컴포넌트는 사용하면 되고, 그렇지 않은 컴포넌트들은 아무런 동작을 하지 않으면 된다.

이렇듯 모든 컴포넌트에 데이터의 변화가 전파되기 때문에 필요없는 render() 함수가 호출된다는 단점이 있다.

 

리덕스는 store라는 곳에서 데이터를 관리하기 때문에 어떤 컴포넌트에서 데이터를 변화시키면, store가 한번에 데이터의 변화를 컴포넌트들에게 알려준다.

상위 컴포넌트와 하위 컴포넌트를 왔다 갔다 하면서 전파하는 것보다 훨씬 효율이 좋지만 여전히 데이터의 변화를 알 필요 없는 컴포넌트들에게도 데이터의 변화가 전달되는 비효율성은 가지고 있다.

 

이렇듯 각각의 장점과 단점이 있는 리액트와 리덕스를 함께 사용하면 단점을 최대한 없애고 장점만을 취할 수 있다.

리덕스를 추가해서 데이터의 변화를 알 필요가 있는 컴포넌트들에게만 정보를 전달할 수 있게된다.

 

리액트를 단독으로 사용했을 때와 리덕스를 추가해서 사용했을 때의 차이를 직접 확인하기 위해 아래 웹 어플리케이션을 준비했다.

이 어플리케이션은 Add Number 라고 적혀있는 곳에 숫자를 입력하고 '+' 버튼을 누르면

Display Number 라고 적혀있는 곳에 Add Number에 적은 숫자가 더해져 보이는 기능을 가지고 있다.

 

이 어플리케이션을 트리로 나타내면 위 그림과 같다.

리액트만 사용해서 구현한 이 어플리케이션은 Add Number에서 숫자가 바뀌었을 때 Add Number Root로 그 값이 전달되고 Root로 다시 값이 전달된다. 그리고 다시 Display Number Root로 값이 전달되고 마지막으로 Display Number에 값이 전달된다.

 

이렇듯 비효율적인 동작을 리덕스를 통해 효율적인 동작이 되게끔 변경해줄 수 있게 된다.

리덕스를 추가하는 방법을 알기 위해 우선 위 어플리케이션의 주요 코드들을 알고 있어야 한다.

App.js
displayNumberRoot.jsx
addNumberRoot.jsx
displayNumber.jsx
addNumber.jsx

 

이제 리덕스를 사용해서 위 코드들을 수정할 것이다.

우선 터미널에서 'npm install redux' 명령어로 패키지에 redux를 설치해준다.

 

그리고 src 디렉토리에 store.js 파일을 만들어 store를 따로 만들어준다.

store.js

createStore에 선이 그어져 있는 것은 무시해도 좋다.

redux에서 createStore가 deprecated 되었으니 다른 코드를 사용하는걸 추천하는 의미로 중앙선이 그어진 것이다.

그대로 사용해도 동작은 한다.

 

createStore를 통해 store를 생성할 때는 reducer() 함수가 첫번째 인자로 꼭 들어가야한다.

익명함수로 reducer() 함수를 구현해뒀고, dispatch를 통해 전달받은 action의 type이 'INCREMENT'이면 state의 원래 number 값에 action의 size를 더해 state를 수정한다.

 

addNumber.jsx

이제 addNumber.jsx 파일로 와서 '+' 버튼을 눌렀을 때 동작을 수정한다.

store.js 파일의 store를 import하고 onclick 이벤트 발생 시 동작하는 함수를 수정해준다.

store.dispatch() 함수를 통해 type은 'INCREMENT'이고 size는 AddNumber의 state에 있는 size값인 action을 reducer에게 전달해준다.

 

여기까지 하면 store의 state 내부에 있는 number 값을 변하지만 display Number에 숫자는 아무리 버튼을 눌러도 변하지 않는다.

displayNumber.jsx

displayNumber.jsx 파일로 가서 또 코드를 수정해준다.

store를 import하고 text타입의 input 태그에 value를 'this.state.numer'로 수정한다.

DisplayNumber의 state 값도 store.getState() 메소드를 사용해서 number 값을 가져오도록 한다.

이렇게 까지만 하면 마찬가지로 어플리케이션에선 변화가 없기 때문에 constructor 함수 내에 subscibe() 함수를 사용해서 state 값이 변하면 특정 함수가 동작하도록 해준다.

익명함수로 DisplayNumber의 state 값을 store의 state 값이 되게끔 한다.

 

코드를 수정하고 어플리케이션을 확인하면 원하던대로 잘 동작하는 것을 볼 수 있다.

 

이제 이 어플리케이션은 Add Number의 데이터가 변해도 Add Number Root와 Root에 변화한 데이터를 전해줄 필요가 없어졌다.

redux의 store에서 데이터를 관리하기 때문이다.

따라서 원래 코드에 있던 props는 모두 제거해도 된다.

 

App.js
displayNumberRoot.jsx
addNumberRoot.jsx
displayNumber.jsx
addNumber.jsx

이렇듯 리액트에 더해서 리덕스를 사용하면서 더 간결하고 관리하기 쉬운 코드가 된 것을 알 수 있다.


부스트코스의 강의 내용을 정리한 포스트입니다.

https://www.boostcourse.org/web231/lecture/1387465

 

웹 프론트엔드 시작하기 (리액트&리덕스)

부스트코스 무료 강의

www.boostcourse.org

BELATED ARTICLES

more