jh.nrtv

Redux -React 상태관리 본문

React

Redux -React 상태관리

wlgus3 2022. 12. 27. 00:48

상태관리

이번 유닛에서는 프론트엔드 개발에서 상태 관리를 보다 더 효율적으로 할 수 있는 방법에 대해서 학습합니다. 바로 컴포넌트와 상태를 분리하여 전역에서 상태 관리를 해줄 수 있게 해주는 상태 관리 라이브러리인 Redux입니다. React 애플리케이션을 개발할 때 Redux를 사용하면 React 컴포넌트 간의 복잡한 데이터 흐름을 따라갈 필요가 없어집니다. 특히 컴포넌트가 많아지고 애플리케이션의 구조가 고도화될수록 Redux를 활용한 상태 관리는 빛을 발합니다.

 

 

전역 상태 관리

리액트는 상태관리를 위한 라이브러리는 아니기에, 상태관리 주요 원칙을 따라가면 컴포넌트 간 서로 느슨하게 결합된 (loose coupled), 구조적으로 아름다운 코드 작성 가능 

 

상태는 '변하는 데이터'이다. 특히 프론트엔드에서는 '동적으로 표현되는 데이터'이다.

 

쇼핑몰 장바구니 화면에도 수 많은 state가 있는 것을 확인할 수 있다. 

 

Side Effect는 상태를 다룰 때 주요 고려 대사이다. 

Side Effect는 '함수의 입력 외에도 함수의결과에 영향을 미치는 요인'을 의미한다. 대표적으로 네트워크 요청, API호출 등이 있다. 

 

React의 주요 개발 원칙 중 하나는 UI를 페이지가 아닌 컴포넌트 단위로 보는 것이다. 

만약 위처럼 <CartItem>이라는 컴포넌트를 만든다면 fetch나 api요청 없이도 이 컴포넌트는 작동해야 하며, 설사 가짜 데이터가 들어오더라도 컴포넌트는 표현 자체에 집중해야 한다. 

 

하지만 앱을 만들다보면 API호출도 해야 하고, side effect가 발생하는 것은 불가피하다. 이러한 side effect에 의존적인 상태도 있을 수 있다. 예를 들어 '로딩 중'을 나타낼 지 여부는 데이터 전송 여부에 따라 달려있다. 앱을 만들 때는 항상 로딩 중 상태도 고려해야 한다. 

 

상태를 '로컬' , '전역' 두 가지로 나눠서 접근해보자 

 

로컬 상태는 특정 컴포넌트 안에서만 관리되는 상태이고, 전역상태는 프로덕트 전체나 여러 컴포넌트가 동시에 관리하는 상태를 말한다. 

 

로컬상태를 구분하는 것은 쉽다. 보통 컴포넌트 내에서만 영향을 끼치는 상태는 로컬 상태이다 .( <CartItem>의 선택수량 ) 

다른 컴포넌트와 데이터를 공유하지 않는 데이터는 대부분 로컬 상태이다. 

 

전역 상태는 다른 컴포넌트와 상태를 공유하고 영향을 끼친다. 

 

JavaScript를 처음 배울 때는 전역 변수를 남용하는 것이 좋지 않다고 배웠지만 경우에 따라서 전역 상태가 필요하다. 

 

서로 다른 컴포넌트가 사용하는 상태의 종류가 다르면, 전역 변수일 필요 없으며 출처 (source)가 달라도 된다. 

그러나, 서로 다른 컴포넌트가 동일한 상태를 다루면, 이 출처는 오직 한 곳이어야 한다. 만일 사본을 쓰는 경우는 두 데이터를 서로 동기화(sync)하는 과정이 필요하기에 번거로워진다. 따라서 한 곳에만 상태를 저장하고 접근해야 하는데 이 '하나의 출처'는 다른 말로 '전역 공간' 이라고 볼 수 있다. 

 

다시 한 번 말하면 데이터 무결성을 위해서, 동일한 데이터는 항상 같은 곳에서 가져오도록 해야 한다. 이는 Single sourse of truth(신뢰할 수 있는 단일 출처 )원칙으로, 프론트엔드 뿐만 아니라 다양한 곳에서 언급되는 원칙이다. 

 

전역 상태 관리 예시1 - 라이트/다크 테마
전역 상태 관리 예시2 - 국제화 설정)
전역 상태 관리 예시3 - 포토샵,일러스트의 undo/redo

상태관리를 도와주는 각종 툴이 있다. 

- React Context

- React

- MobX

 

상태관리 툴은 어떤 문제를 해결하나?

- 전역 상태 저장소 제공

- props drilling 문제 해결 

 

상태관리 툴이 반드시 필요한 것은 아니기에 장단점을 분명히 인지하고 상태 관리 툴을 쓰는 것이 필요하다.  

중요한 것은 상태 관리의 기본기라고 볼 수 있는 '상태가 어디에 위치해야 하는지'를 먼저 익히는 것이다. 

 


Props Drilling

Props Drilling이란?

Props Drilling은 상위 컴포넌트의 state를 props를 통해 전달하고자 하는 컴포넌트로 전달하기 위해 그 사이는 props를 전달하는 용도로만 쓰이는 컴포넌트들을 거치면서 데이터를 전달하는 현상을 의미한다.  -> 위 그림처럼 컴포넌트 A의 state를 컴포넌트 D로 전달하기 위해선 사이에 있는 컴포넌트 B, C를 거쳐야 함.

 

Props Drilling의 문제점

Props의 전달 횟수가 5회 이내로 많지 않다면 Props Drilling 은 큰 문제가 되지 않는다. 하지만 규모가 커지고 구조가 복잡해지면서 Props의 전달 과정이 늘어난다면 아래와 같은 문제가 발생.

  • 코드의 가독성이 매우 나빠지게 됩니다.
  • 코드의 유지보수 또한 힘들어지게 됩니다.
  • state 변경시 Props 전달 과정에서 불필요하게 관여된 컴포넌트들 또한 리렌더링이 발생합니다. 따라서, 웹성능에 악영향을 줄 수 있습니다.

 

해결 방법

과도한 Props Drilling을 방지하기 위한 방법으로는 컴포넌트와 관련있는 state는 될 수 있으면 가까이 유지하는 방법상태관리 라이브러리를 사용하는 방법이 있습니다. 상태관리 라이브러리를 사용하게 되면 전역으로 관리하는 저장소에서 직접 state를 꺼내쓸 수 있기 때문에 Props Drilling을 방지하기에 매우 효과적입니다. 이번 유닛에서는 다양한 상태관리 라이브러리(Redux, Context api, Mobx, Recoil 등) 중 Redux를 다룰 예정입니다.

 

비교1 - 가독성 좋아짐

리액트 사용

https://stackblitz.com/edit/react-bvmiba?file=src%2FApp.js 

 

상태관리 라이브러리를 사용하지 않는 경우 - StackBlitz

A create-react-app project based on react and react-dom.

stackblitz.com

리덕스 사용

https://stackblitz.com/edit/react-dky3fz?file=src%2FApp.js 

 

상태관리 라이브러리(Redux)를 사용하는 경우 - StackBlitz

A create-react-app project based on react and react-dom.

stackblitz.com

 

비교2 - 불필요한 리렌더링 줄임

리액트 사용

https://stackblitz.com/edit/react-ts-qpgq6d?file=App.js 

 

Props Drilling 예시 - StackBlitz

React + TypeScript starter project

stackblitz.com

리덕스 사용

https://stackblitz.com/edit/react-ts-szkjfd?file=App.js 

 

Redux 예시 - StackBlitz

React + TypeScript starter project

stackblitz.com

 

 


 ✅개발 시작 전에  반드시 컴포넌트 구조와 데이터 흐름을 먼저 그림으로 그려보는 것이 필요하다. 

 

 

<input type ="number>   -> 이런식으로 input 태그에 type을 number로 주면 인풋 창에 자동으로 위아래 조절 버튼 생김 

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number

 

<input type="number"> - HTML: HyperText Markup Language | MDN

<input> elements of type number are used to let the user enter a number. They include built-in validation to reject non-numerical entries.

developer.mozilla.org