Redux 데이터 흐름(feat. Flux)

김재훈·2023년 1월 1일
0
post-thumbnail
post-custom-banner

tl;dr

  • Redux를 통해 상태를 전역에서 관리할 수 있다.
  • Flux 패턴으로 전역 상태도 단방향 흐름을 유지할 수 있다.

들어가며

순수 React만을 사용하여 상태 관리를 하다 보면 숱하게 많은 어려움을 겪게 됩니다. React의 단방향 데이터 흐름이라는 특성 때문에 서로 다른 자식 컴포넌트가 같은 상태를 공유해야 하는 경우 공통된 부모 컴포넌트로 상태와 상태 갱신 함수를 올리고, Props Drilling이라는 기법을 통해 데이터를 전달해야 합니다.

Props Drilling

Props Drilling은 상위 컴포넌트가 가지고 있는 상태를 props를 통해 실제 그 상태를 사용하려는 컴포넌트에게 전달하는 기법입니다. 하지만 Props Drilling만으로 상태를 관리하다 보면 여러 문제상황을 만나게 되는데요. 아래 시나리오를 따라가며 어떤 문제들이 발생하는지 알아봅시다.

#문제1 코드의 가독성을 해친다.
컴포넌트의 구조가 아래 트리와 같이 구성되어 있다고 가정해봅시다.
그림1. Props Drilling을 보여주기 위한 컴포넌트 트리구조 예시

<SecondChild D>가 화면에 Number 타입의 count 상태를 렌더링해주는 컴포넌트고, <SecondChild A>에서 +, - 버튼을 누를 때마다 count 상태가 변경되는 +1, -1되는 구조라고 하면 양 끝 모두에 상태를 내려주기 위하여 상태를 가져야 하는 공통 부모는 <Root> 컴포넌트가 됩니다.

여기서 첫번째 문제의 의미를 알 수 있는데요. 지금은 깊이가 3단이라서 추적이 쉽지만 하위로 컴포넌트가 늘어나다 보면 이 상태를 어디서부터 내려받는지, 상태 갱신이 어디서 되는지 추적하기가 매우 어려워집니다.

#문제2 불필요한 리렌더링이 발생한다.
위 시나리오에서 count 상태가 변경됐을 때 렌더링이 다시 발생해야 하는 컴포넌트는 <SecondChild D>인데요. 해당 컴포넌트만이 실제 상태를 렌더링에 사용하고 있기 때문입니다.
그림2. 그림1에서 렌더링이 다시 되어야 하는 컴포넌트에 주황색 배경칠

하지만 실제로는 모든 컴포넌트에서 리렌더링이 발생합니다. 그 이유는 <Root> 컴포넌트가 상태를 가지고 있기 때문인데요. React는 상태 값이 업데이트될 때 useState()로 상태가 선언된 컴포넌트를 리렌더링하므로 <Root>를 포함한 하위의 모든 컴포넌트가 리렌더링됩니다.
그림3. 그림1에서 모든 컴포넌트에 주황색 배경칠

Redux와 Flux

Props Drilling 기법으로 상태를 교환할 때 발생하는 문제점을 해결하기 위한 도구가 Redux로, 상태를 Store라는 한 공간에 저장한 뒤 전역에서 이 Store에 접근할 수 있게 합니다.

Redux를 사용할 때는 아래 세 가지 원칙을 지켜야 합니다.
1.Single source of truth
- 동일한 데이터는 항상 같은 곳에서 가지고 와야 합니다.
- Redux에서는 Store라는 하나의 데이터 저장공간을 활용하여 구현합니다.
2. State is read-only
- Redux 상태는 읽기 전용이므로 Action 객체를 통해 변경해야 합니다.
3. Changes are made with pure functions
- 예상치 못 한 동작을 방지하기 위해 순수함수로 작성해야 합니다.

Flux 패턴은 Redux를 효율적으로 사용하기 위한 데이터 흐름 패턴입니다. 이 패턴은 Redux 원칙을 효율적으로 지키면서 여러 컴포넌트에서 발생하는 데이터 변경을 하나의 단방향 흐름으로 유지하도록 도움을 줍니다. 이를 위해 각 요소들의 역할을 제한하는데 예를 들면 아래와 같습니다.
1. 사용자에게 보이는 화면에서 사용자에 의해 발생한 '입력'(마우스 클릭 등을 포함한)으로부터 액션이 발생할 준비를 합니다.
2. 액션은 상태를 어떻게 변경해야 할지를 명시한 객체입니다. 직접 기재할 수도 있지만 일반적으로 액션 생성자라고 하는 액션을 리턴하는 함수를 작성합니다. 액션 생성자는 액션을 포맷에 맞게 만들어 디스패쳐에 넘깁니다.
3. 디스패쳐는 들어온 액션을 확인해서 알맞은 스토어로 보내는 역할을 합니다. 스토어는 자신 스스로 값을 설정하지 않으며 모든 액션을 받기 때문에 디스패쳐의 선별 과정이 필요합니다.
4. 스토어가 업데이트 되면 이를 구독 중인 컴포넌트들에서 리렌더링이 발생합니다.

위의 말은 아래 글을 요약한 글로 그림 자료가 포함된 상세 내용을 보면 이해가 더욱 쉽습니다.
https://bestalign.github.io/translation/cartoon-guide-to-flux/

마지막으로

Redux가 필요한 이유와 그게 어떤 것인지, 사용할 때는 어떤 패턴으로 사용하는지를 정리했습니다. 잘못된 내용이나 오탈자가 발견된다면 코멘트 부탁드리며, Flux 패턴에 대한 글은 강추 드리는 글이니 꼭 한 번 읽어보시면 좋을 것 같습니다.

profile
개발하면서 새롭게 배운 내용, 시행착오한 내용들을 잊지 않기 위해 기록합니다.
post-custom-banner

0개의 댓글