Skip to content

Commit

Permalink
[@xstate/store] Add shallowEqual (#5085)
Browse files Browse the repository at this point in the history
* Add the shallowEqual comparator

* Changeset

* Remove test

* Update packages/xstate-store/test/react.test.tsx

Co-authored-by: Mateusz Burzyński <[email protected]>

---------

Co-authored-by: Mateusz Burzyński <[email protected]>
  • Loading branch information
davidkpiano and Andarist authored Sep 18, 2024
1 parent 4d8bb95 commit 51437a4
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
24 changes: 24 additions & 0 deletions .changeset/friendly-jokes-whisper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
'@xstate/store': minor
---

The `shallowEqual` comparator has been added for selector comparison:

```tsx
import { shallowEqual } from '@xstate/store';
import { useSelector } from '@xstate/store/react';

import { store } from './store';

function MyComponent() {
const state = useSelector(
store,
(s) => {
return s.items.filter(/* ... */);
},
shallowEqual
);

// ...
}
```
1 change: 1 addition & 0 deletions packages/xstate-store/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { shallowEqual } from './shallowEqual';
export { fromStore } from './fromStore';
export { createStore, createStoreWithProducer } from './store';
export * from './types';
37 changes: 37 additions & 0 deletions packages/xstate-store/src/shallowEqual.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// From https://github.com/reduxjs/react-redux/blob/720f0ba79236cdc3e1115f4ef9a7760a21784b48/src/utils/shallowEqual.ts
function is(x: unknown, y: unknown) {
if (x === y) {
return x !== 0 || y !== 0 || 1 / x === 1 / y;
} else {
return x !== x && y !== y;
}
}

export function shallowEqual(objA: any, objB: any) {
if (is(objA, objB)) return true;

if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}

const keysA = Object.keys(objA);
const keysB = Object.keys(objB);

if (keysA.length !== keysB.length) return false;

for (let i = 0; i < keysA.length; i++) {
if (
!Object.prototype.hasOwnProperty.call(objB, keysA[i]) ||
!is(objA[keysA[i]], objB[keysA[i]])
) {
return false;
}
}

return true;
}

0 comments on commit 51437a4

Please sign in to comment.