Skip to content

Commit

Permalink
fix(react): make useAtomSelector wait for idle time to do failsafe …
Browse files Browse the repository at this point in the history
…cleanup (#113)
  • Loading branch information
bowheart authored Sep 7, 2024
1 parent 25b8c89 commit f88996e
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 9 deletions.
1 change: 1 addition & 0 deletions packages/atoms/src/classes/Selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export class Selectors {
{
cache?: SelectorCache
ignorePhase?: number
timeoutId?: ReturnType<typeof requestIdleCallback | typeof setTimeout>
}
> = {}

Expand Down
26 changes: 17 additions & 9 deletions packages/react/src/hooks/useAtomSelector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,23 @@ export const useAtomSelector = <T, Args extends any[]>(

// React StrictMode's double renders can wreak havoc on the selector cache.
// Clean up havoc
queueMicrotask(() => {
cancelCleanup = false

Object.values(selectors._storage).forEach(storageItem => {
if (storageItem.cache?.id) {
selectors._destroySelector(storageItem.cache.id)
}
})
})
if (storage.timeoutId == null) {
const removeCruft = () => {
storage.timeoutId = null
cancelCleanup = false

Object.values(selectors._storage).forEach(storageItem => {
if (storageItem.cache?.id) {
selectors._destroySelector(storageItem.cache.id)
}
})
}

storage.timeoutId =
typeof requestIdleCallback !== 'undefined'
? requestIdleCallback(removeCruft, { timeout: 500 })
: setTimeout(removeCruft, 500)
}

return cleanup
}, [cache])
Expand Down
4 changes: 4 additions & 0 deletions packages/react/test/units/useAtomSelector.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,8 @@ describe('useAtomSelector', () => {
const button = await findByTestId('button')
const div = await findByTestId('text')

jest.runAllTimers()

expect(ecosystem.selectors.findAll()).toMatchInlineSnapshot(`
{
"@@selector-unnamed-1": SelectorCache {
Expand Down Expand Up @@ -531,6 +533,8 @@ describe('useAtomSelector', () => {

const div = await findByTestId('text')

jest.runAllTimers()

expect(div.innerHTML).toBe('1')
expect(renders).toBe(2) // 2 rerenders + 2 for strict mode
expect(ecosystem._graph.nodes).toMatchSnapshot()
Expand Down

0 comments on commit f88996e

Please # to comment.