jotai는 useSyncExternalStore 를 사용하지 않는다.
ref - https://blog.axlight.com/posts/why-use-sync-external-store-is-not-used-in-jotai/
- jotai 는 내부적으로 useState (useReducer)를 사용한다.
- 또한, useSyncExternalStore에서
sync
는time slicing
과 호환되지 않음을 의미한다. concurrent mode 에서 time slicing 이란?
// 동기적(Synchronous) 업데이트
const value = useSyncExternalStore(subscribe, getSnapshot);
- 위에서, 외부 스토어가 변경되면 즉시 모든 컴포넌트를 동기적으로 업데이트 함.
- 따라서, time-slicing 이 불가능함.
반면..
const [value, setValue] = useState(initialValue);
startTransition(() => {
// 우선순위가 낮은 업데이트
// 중간에 중단되고 다른 작업이 끼어들 수 있음
setValue(newValue);
});
- 리액트 내부 상태 (useState)를 사용하면, 우선순위가 낮은 업데이트를 지정할 수 있고, 따라서 해당 업데이트 작업이 중간에 중단되고 다른 작업이 끼어들 수 있음.
- 즉, time-slicing 이 가능함.
다시 정리하자면
- useSyncExternalStore
- 데이터 일관성을 보장한다. (tearing 방지)
- 하지만, 동기적(Sync) 업데이트로 인한 성능 및 응답성이 저하된다.
- time-slicing 이 불가능하다. (렌더링 중단/ 재개 불가)
- useState/useReducer
- time-slicing 가능 (렌더링 중단/재개 가능)
- 더 나은 응답성 (사용자 입력에 즉시 반응 가능)
- 하지만 일시적인 tearing 가능성
그리고, jotai 는 일부러 useSyncExternalStore 를 사용하지 않음
- time-slicing의 이점을 활용하기 위해서이고,
- 이를 통해서 더 나은 사용자 경험을 제공하기 위함.
- 일시적인 tearing edge case 를 감수하고서라도 위와 같은 성능을 선택함.