10장. 상태 관리
10.1 상태 관리
10.1.1 상태
- 지역 상태(useState, useReducer) / 전역 상태 / 서버 상태(React Query, SWR)
10.1.2 상태를 잘 관리하기 위한 가이드
시간이 지나도 변하지 않는다면 상태가 아니다
- 객체의 참조 동일성을 유지하기 위해 useMemo 를 사용하는 것은 성능 향상을 위해 사용하는 것이 아니므로 올바른 사용 방법이 아니다
useState(() => new Store())
같이 초깃값을 콜백으로 지정하는 지연 초기화 방식을 도입하여 비용을 줄이는 것이 좋다- 제일 좋은 방법은 렌더링에 영향을 받지 않는 useRef 를 사용하는 것이 좋다. 다만 렌더링 마다 새로운 인스턴스 생성을 막기 위해 아래와 같이 작성을 추천
import { useRef } from 'react';
const store = useRef<Store>(null);
if (!store.current) {
store.current = new Store();
}
** [p.309] 지연 초기화 사용 팁은 좋으나 당연한 소리를....
파생된 값은 상태가 아니다
- 리액트 앱에서의 상태도 SSOT(Single Source Of Truth) 를 적용해야 한다
- props 로 받은 데이터의 동기화를 위해 useEffect 를 사용해서는 안되며, 동일 출처에서 데이터를 사용할 수 있도록 상태 끌어올리기(Lifting State Up) 기법을 사용한다
import React, { useState } from 'react';
type UserEmailProps = {
email: string;
setEmail: React.Dispatch<React.SetStateAction<string>>;
};
const UserEmail: React.VFC<UserEmailProps> = ({ email, setEmail }) => {
const onChangeEmail = (event: React.ChangeEvent<HTMLInputElement>) => {
setEmail(event.target.value);
};
return (
<div>
<input type="text" value={email} onChange={onChangeEmail} />
</div>
);
};
- 또한 내부 상태 동기화를 위해서 모든 값을 state 로 지정하는 것이 아니라, 일반 변수로 변경하여 특정 state 가 변경 시 값을 계산 후 변수에 담는 방법을 통해 단일 출처를 유지할 수 있다
- 성능적 측면으로는 useMemo 를 사용하여 결과를 메모제이션 하면 성능 개선도 가능하다
useState vs useReducer, 어떤 것을 사용해야 할까?
- 구조가 복잡하고 클 경우 useState 보다는 useReducer 를 통해 관리하는 편이 좋다
** [p.313] 당연한 소리를2... ㅋㅋㅋ
10.1.3 전역 상태 관리와 상태 관리 라이브러리
Context API
import { useReducer } from 'react';
function App() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<StateProvider.Provider value={{ state, dispatch }}>
<ComponentA />
<ComponentB />
</StateProvider.Provider>
);
}
- 위와 같이 Context API 를 통해 전역 상태 관리를 하는 것은 주입된 값이나 참조가 변경 될 때마다 모든 컴포넌트가 리렌더링 되기 때문에 대규모 어플리케이션에서는 권장하지 않는다
- 적절한 관심사 분리를 통해 구성은 가능하나 불필요한 리렌더링과 상태 복잡도의 증가를 막기는 어렵다
10.2 상태 관리 라이브러리
10.2.1 MobX
- 객체 지향 프로그래밍과 반응형 프로그래밍 패러다임이 반영된 라이브러리
- 데이터가 언제 어떻게 변하는지 추적이 어려움이 존재
10.2.2 Redux
- 함수형 프로그래밍의 영향을 받은 라이브러리, 오랜 기간 검증이 되었으며 상태 변경 추적에 용이하다
- 단순 상태 설정에도 많은 보일러 플레이트가 필요하고, 난도가 높은 단점이 존재
10.2.3 Recoil
- Redux 에 비해 보일러 플레이트가 적고 난이도가 쉽다
- 아직 정식 출시가 안된 상태이기 때문에 충분한 검증이 안되어 있음
10.2.4 Zustand
- Flux 패턴을 사용하면 간단한 형태의 훅으로 편리한 기능 제공
** [p.323] Zustand 는 단점 없나요!? ㅎㅎㅎㅎ ** [p.324] 역시 단순한게 최고! 그럼 이젠 다 Zustand 쓰실듯? + 그 와중에도 취향 차이 있는건 재미있습니다