본문 바로가기
개발 및 알고리즘/개발

[Redux] Redux를 사용하는 이유

by 0xseo 2024. 3. 30.
반응형

리액트에서는 컴포넌트 단위로 프로젝트를 구성하기 때문에 컴포넌트 사이에 데이터를 주고받는 방식이 명확해야 한다. 보통 하나의 루트 컴포넌트 (일반적으로 App.js)에서 상태를 정의하고, 이를 상속함으로써 하위 컴포넌트에서도 관리할 수 있게 한다.

하위 컴포넌트에서 상태를 직접 정의하지 않고 부모 컴포넌트에서 정의한 후 이를 통해서 소통하는 이유는, 하위 컴포넌트끼리 직접 소통하기가 까다롭고 코드가 복잡해지기 때문이다. (보통 ref를 사용하여 작업한다고 한다.)

 

이렇게 부모 컴포넌트에서 상태를 관리하면서 상속을 통해 소통하게 되면 관리하기 편하면서 직관적인 구조가 된다. 그러나 문제는 앱의 규모가 커져 상속의 단위나 컴포넌트의 개수가 늘어났을 때이다.

 

규모가 커질수록 데이터도, 데이터를 업데이트하거나 생성하는 함수도 기하급수적으로 늘어날 것인데 이 전부가 루트 컴포넌트에 소속되면 App 파일의 코드도 길어지고, 복잡하고 관리도 힘들어진다.

 

 

예를 들어 루트 컴포넌트가 G 컴포넌트에게 데이터를 제공할 때는 이렇게 루트 →  A → C → F → G를 거쳐 먼 길을 가야 하고, 또 props의 value라는 이름을 다른 이름으로 바꾸게 되면 루트, A, C, F, G 컴포넌트에서 각각 이름을 수정해야 하기 때문에 파일 4-5개에서 직접 수정해야 한다. 매우 귀찮고 복잡해지는 것이다!

 

// App.js 에서 A 렌더링
<A value={5}>

// A.js 에서 C 렌더링
<C value={this.props.value} />

// C.js 에서 F 렌더링
<F value={this.props.value} />

// F.js 에서 G 렌더링
<G value={this.props.value} />

 


 

이때 리덕스를 사용하면 이런 상황을 방지할 수 있다!

리덕스는 컴포넌트 단위에서 상태를 관리하지 않는다. 리덕스 라이브러리를 사용할 때에는 최상단 컴포넌트를 Provider 컴포넌트로 감싸야 하는데, 이곳에 ‘리덕스 스토어’가 생성되어 컴포넌트 바깥에서 상태를 관리하게 된다.

이때 각 상태를 사용하는 하위 컴포넌트들은 리덕스 스토어에게 특정 함수를 전달하면서 ‘구독’ 처리를 한다. 나중에 상태 값이 변경되는 경우 리덕스 스토어에서 전달받은 함수를 호출해 주면 상태가 업데이트되었음을 알 수 있기 때문이다.

 

그렇다면 상태 업데이트는 어떻게 할까? 각 컴포넌트에서는 dispatch라는 함수를 통해 action을 리덕스 스토어에게 전달한다. 이때 action은 각 상태에 변동을 줄 때 참조할 수 있는 객체를 말한다. action 객체는 type을 반드시 필요로 하는데, 리덕스 스토어에서는 전달받은 action 객체의 type을 통해 상태에 어떤 변동을 줄지 파악할 수 있다. 또 type뿐만 아니라 다른 데이터를 넣어서 얼마나 변동을 줄지 등 다양한 정보를 전달할 수 있다.

 

 

// action : { type: 'INCREMENT', diff: 2 }

 

리덕스 스토어에는 전달받은 action 객체의 type에 따라 상태 업데이트 로직을 정의해 놓은 함수가 있다. 이 함수를 ‘리듀서’라고 한다. (물론 우리가 직접 정의해주어야 한다.)

 

리듀서 함수는 파라미터로 받은 현재 상태 (state)와 액션 객체 (action)를 참조하여 새로운 상태 객체를 만든 후 반환한다. 반환뙨 상태 객체는 리덕스 스토어에 새롭게 저장되는 것이다.

 

 

그렇게 상태에 변화가 생기면 리덕스 스토어는 구독 처리하며 전달받은 listener 함수를 호출하게 되고, 각 컴포넌트는 상태가 업데이트되었음을 알게 되어 리렌더링을 하게 되는 것이다. 즉 컴포넌트 사이 공통 부모를 찾아 상속이라는 먼 길을 통해 상태를 read/write하는 것이 아닌, 컴포넌트 외부 라이브러리를 통해 상태를 전달받기 때문에 아무리 깊숙한 컴포넌트에서도 쉽고 간단하게 데이터를 받고, 업데이트할 수 있게 되는 것이다!

 

참조: https://velopert.com/3528

반응형