refactor: deepCompare → shallow 비교로 전환 (zustand 방식, breaking change) - #5
Merged
Conversation
Breaking change: React 어댑터의 selector 비교 방식을 deep compare에서 shallow compare로 변경. ## 변경 사항 - src/core/shared/shallow.ts: shallow 함수 구현 (zustand 참고) - Object.is → 1단계 비교 - Map: entries() 비교 - Set: iterator 비교 - 배열: iterator 비교 - 일반 객체: Object.entries() 비교 - Date: 프로토타입 비교 (같으면 같음 — selector에서 getTime() 권장) - 순환 참조 안전 (1단계만 비교) - src/core/React/createUseState.ts: - deepCompare 제거, shallow를 useStoreState에 내장 (항상 shallow 적용) - useSyncExternalStore에 직접 selector 전달 방식으로 단순화 - 메모이제이션 로직을 shallow 기반으로 재작성 - src/core/shared/deepCompare.ts: 삭제 - test/shallow.test.ts: 21개 단위 테스트 - 원시값, 객체, 배열, Map, Set, Date, 순환 참조 안전성 - README.md / README.ko.md: 마이그레이션 가이드 추가 - deep → shallow 변경 이유와 영향 - 깊은 비교가 필요한 경우 useMemo 권장 ## 성능 개선 - 매 렌더마다 전체 state를 재귀 순회 → 1단계 비교만 - Map/Set/Date 올바른 비교 (기존 deepCompare 버그 수정) - 순환 참조 스택 오버플로우 해결 ## 기존 테스트 회귀 115개 기존 테스트 전부 통과 (변경 없음) + 21개 shallow 테스트 = 136개 전부 통과 Closes #3
High: shallowSelector 클로저가 store 변경에 안전하지 않은 문제 수정 - getSnapshot과 getServerSnapshot이 별도의 createShallowSelector 인스턴스를 생성하도록 분리 - store 의존성이 두 useMemo에 모두 포함되어 store 변경 시 클로저가 재생성됨 - 서버/클라이언트 hydration 불일치 및 stale 참조 문제 해결 Medium: Date 비교를 getTime() 기반으로 개선 - shallow 함수에 Date instanceof 체크 추가 - 다른 시각의 Date가 같다고 판단되는 문제 해결 - 테스트 및 README 마이그레이션 가이드 업데이트 Low: shallow.ts 끝 개행 추가
- .changeset/shallow-selector-breaking.md: major changeset documenting the deepCompare -> shallow breaking change with migration notes - README.md / README.ko.md: bump migration heading to v2.0.0 (was v1.1.0), mark as breaking change, add 'Keep selector identity stable' section explaining how inline selectors reset createShallowSelector's cache and recommending module-scope selectors or useCallback
ayden94
force-pushed
the
refactor/shallow-compare
branch
from
July 19, 2026 09:42
9933448 to
4e99628
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #3 —
deepCompare를shallow비교로 전환 (zustand 방식).Breaking Change
React 어댑터의 selector 비교 방식을 deep compare에서 shallow compare로 변경. shallow가 항상 적용됨 (옵션 아님).
Changes
New:
src/core/shared/shallow.tszustand의
shallow구현을 참고하여 작성:Object.is→ 1단계 비교Map:entries()비교Set: iterator 비교Object.entries()비교Date: 프로토타입 비교 (같으면 같음 — selector에서getTime()권장)src/core/React/createUseState.tsdeepCompare제거shallow를useStoreState에 내장 — 항상 shallow 적용useSyncExternalStore에 직접 selector 전달 방식으로 단순화Deleted:
src/core/shared/deepCompare.tsTests:
test/shallow.test.ts— 21개Docs
Performance
Verification
기존 115개 테스트 전부 통과 (회귀 없음) + 21개 shallow 테스트 추가.
Closes #3