Skip to content

Latest commit

 

History

History
66 lines (40 loc) · 5.38 KB

week3_생각과제.md

File metadata and controls

66 lines (40 loc) · 5.38 KB

React에서 상태관리는 왜 필요한가

리액트는 데이터가 부모에서 자식으로만 흐르는 단반향 데이터 흐름을 가지고 있다.

자식 컴포넌트끼리 데이터를 전달하고 싶다면 자식1 → 부모 → 자식2 이런식의 흐름을 가져가야 할 수도 있다. 또한 컴포넌트가 많아지면 사용하지 않는 props임에도 오직 전달을 위해서 props를 넘겨줘야하는 불필요한 상황이 생길 수도 있고 props drilling 때문에 유지보수도 어려워진다.

따라서 React에서는 다양한 상태관리 라이브러리를 사용해서 조금이나마 더 편한 방법을 제공한다.

관리 해야 하는 상태에 대한 기준은 무엇인가?

  1. 기본적으로 일반적인 경우에는 지역 상태로 데이터를 관리하는 것을 권장한다.
  2. 지역 상태로 데이터를 관리 시 다수의 컴포넌트 간에 상태 의존성이 높아진다면 전역 상태로 데이터를 관리하는 것을 권장한다.
  3. 전역 상태 관리 시 서버에서 가져오는 데이터(db)와, 단순하게 UI 상태를 나타내는 데이터는 분리하여 다룬다.
  4. 서버 데이터 캐싱 시 전역 상태로 다루면 안된다. 서버 상태를 관리하려면, SWR이나 React-Query 와 같은 서버 캐싱 전용 라이브러리를 사용하는 것을 권장한다.

어떤 상태관리 라이브러리를 어떤 상황에서 사용해야 할까?

( 장단점 또는 간단 비교 분석 )

redux

  • redux는 데이터가 Centralized 되어 있어 Predictable 하고 데이터 흐름이 단방향이라 Debuggable (디버깅이 쉽다) 하다. redux의 생태계가 구축되어 있어 필요에 맞게 Flexible하게 구현 가능하다. (비동기 하려면 redux-thunk & redux-saga 같은 라이브러리를 추가로 사용해야한다.)
  • Redux dev Tool을 사용할 수 있다.

Context API

  • Provider를 나눠서 관리가 가능하고, 최상단이 아닌 관련된 컴포넌트 들의 상위에 Provider를 감싸기만 하면 되기 때문에 데이터가 필요한 컴포넌트들에서만 상태를 관리 할 수 있다.

Recoil

  • Redux, Mobx와 달리 Recoil은 리액트 만을 위해 생긴 라이브러리다
  • Recoil은 React에서 공유상태를 간단한 get/set 인터페이스로 사용할 수 있게 해주는 API다.
  • atom과 selector 두가지 요소로 상태관리를 한다.
  • atom : 상태의 단위이며, 업데이트와 구독이 가능하다
  • Selector : atoms나 다른 selectors를 입력으로 받아들이는 순수 함수(pure function)다.

더불어 Recoil 에 정의된 상태는 상태를 사용하는 컴포넌트를 수정하지 않고도 상태를 파생된 데이터로 대체할 수 있으며 더불어 동기식 혹은 비동기적으로 해당 상태를 업데이트 할 수 있다.

Redux는 보일러플레이트 코드가 많기 때문에 소규모의 프로젝트에서는 적합하지 않지만 Redux dev Tool을 이용해 편의성을 가져갈 수 있을 것이다.

Context API는 해당 값 외의 다른 값이 변경될때도 컴포넌트가 재호출되어 리렌더링이 발생한다. 따라서 목표 값에 따라 분리 해서 관리를 해야하는데, 목표 값이 많아 질 수록 컴포넌트가 많아져서 성능 이슈가 발생하기 때문에 이러한 단점을 숙지하고 사용해야한다. 또한 Context는 단일 값만 저장할 수 있으며, 자체 소비자(consumer)를 가지는 여러 값의 집합을 담을 수는 없다.

recoilredux와는 다르게 보일러 플레이트 코드가 많지 않고 또한 redux처럼 외부 라이브러리 (saga, thunk)를 추가해야할 경우가 많지 않고 hook처럼 리액트의 상태를 간단하게 변경하고 이용 가능하기 때문에 러닝커브가 적다는 생각이 든다.

React에서 렌더링을 효과적으로 관리하는 방법은 무엇이 있을까?

무분별한 리렌더링을 막아야합니다. 그러기위해선 렌더링이 발생하는 경우를 먼저 알아봐야한다.

  • 내부 상태(state) 변경시
  • 부모에게 전달받은 값(props) 변경시
  • 중앙 상태값(Context value 혹은 redux store,) 변경시
  • 부모 컴포넌트가 리렌더링 되는 경우
  • Hook 변경시

이를 위해 어떤 식으로 비즈니스 설계를 진행해야 할까

  • React.memo를 사용한다.

사용자의 컴포넌트 타입을 인자로 전달받고 래핑된 새 컴포넌트를 반환합니다. 래퍼 컴포넌트의 기본 동작은 props가 변경되었는지 확인하고 변경되지 않은 경우 리렌더링되지 않도록 합니다. 함수 컴포넌트와 클래스 컴포넌트 둘 다 React.memo()를 사용해 래핑할 수 있다. (커스텀 비교 콜백을 전달할 수 있지만, 오직 이전 props와 새 props의 비교만 할 수 있으므로, 커스텀 비교 콜백은 주로 모든 props 대신 특정 prop만 비교하기 위해 사용됨)

  • useMemo를 사용한다.

리액트 컴포넌트가 이전과 정확히 동일한 요소 참조를 반환하면 리액트는 해당하는 특정 하위 컴포넌트의 리렌더링을 건너뛰게 한다.

이는 종속성 배열의 값이 변경될 때까지 동일하게 유지됩니다.

https://velog.io/@superlipbalm/blogged-answers-a-mostly-complete-guide-to-react-rendering-behavior