generated from NaverPayDev/ts-monorepo-template
-
Notifications
You must be signed in to change notification settings - Fork 4
Closed
Description
안녕하세요, 해당 글을 통해 vanilla-store에 흥미를 갖게 되었고 라이브러리를 사용해보니 매우 만족스러웠습니다. (무엇보다 Zero Dependency!!!)
한 가지, useSetStore 훅에 대한 작은 제안이 있어 이슈를 남깁니다. 현재 useSetStore가 스토어를 구독하여 리렌더링이 발생하는 것으로 보이는데, 이 부분에 대해 함께 논의해보면 어떨까 합니다.
원인
- useSyncStore 함수 내부에서 useSyncExternalStore함수를 호출하여 현재 호출한 컴포넌트를 store에 구독한뒤 리액트 스케쥴러에 리렌더링을 예약하고, 현재 store의 snapshot을 반환합니다.
- 이로 인해 useSetState를 호출하는 컴포넌트도 store값이 변경될 때마다 리렌더링이 발생합니다.
- useSetStore는 set 함수에만 접근이 필요할 때 사용하는 훅입니다. 이 훅이 '쓰기 전용'으로 사용될 때 불필요한 리렌더링을 방지한다면, 라이브러리의 성능 최적화에 더 큰 도움이 될 것으로 보입니다!
export function useSetStore<State>(store: VanillaStore<State> | VanillaSelect<State>, initialValue?: State) {
useSyncWithInitialValue(store, initialValue)
useSyncStore(store, initialValue) // 불필요한 상태 구독 중
return store.set
}해결 방안
- useSetState에서 useSyncStore 함수 호출 코드를 삭제합니다.
- 이로 인해 더이상 useSetStore를 사용중인 컴포넌트 함수는 리렌더링 되지 않습니다.
export function useSetStore<State>(store: VanillaStore<State> | VanillaSelect<State>, initialValue?: State) {
useSyncWithInitialValue(store, initialValue)
// useSyncStore(store, initialValue) 삭제!!!!!
return store.set
}재현
- 코드 샌드박스에서 브라우저 콘솔을 열고 나이 증가 버튼 또는 이름 입력 창에 글자를 타이핑하게 되면
<Input />컴포넌트 또한 리렌더링 되는 모습을 확인하실 수 있습니다.
기타
- 아직 라이브러리 전체를 이해하진 않았기에 제가 모르는 또다른 이유가 있거나 잘못 이해한 점이 있다면, 편히 알려주시면 감사하겠습니다!!
keemhyunseok and Turtle-Hwanyujeong-jeonyujeong-jeon
Metadata
Metadata
Assignees
Labels
No labels