Skip to main content

useAtomSelector

import { useAtomSelector } from '@zedux/react'

A React hook that accepts an AtomSelector and registers a dynamic graph dependency on the selector's cache.

The selector will rerun every time any of its own dynamic dependencies update. The React component that uses this injector will only rerender when the selector result changes.

Caches the selector's result in the ecosystem's .selectors if it hasn't been cached yet. If this selector has been cached before with the same arguments, the selector doesn't run, and useAtomSelector() returns the cached result.

Unlike all other atom selection APIs (injectAtomSelector() and the select AtomGetter), useAtomSelector() actually respects the argsComparator AtomSelectorConfig option.

Example

Live Sandbox
1234567891011121314151617181920212223242526272829303132333435
const countersAtom = atom('counters', () => {
const store = injectStore({ counterA: 1, counterB: 1 })

return store
})

function Counters() {
const counterA = useAtomSelector(({ get }) => get(countersAtom).counterA)
const instance = useAtomInstance(countersAtom)
const { setState } = instance
const rendersRef = useRef(0)
rendersRef.current++

return (
<>
<div>Number of renders: {rendersRef.current}</div>
<div>Counter A (dynamic): {counterA}</div>
<button
onClick={() =>
setState(state => ({ ...state, counterA: state.counterA + 1 }))
}
>
Increment Counter A
</button>
<div>Counter B (static): {instance.getState().counterB}</div>
<button
onClick={() =>
setState(state => ({ ...state, counterB: state.counterB + 1 }))
}
>
Increment Counter B
</button>
</>
)
}

Miscellaneous:

// only rerender when `someField` changes:
const selectedVal = useAtomSelector(({ get }) => get(myAtom).someField)

const withParams = useAtomSelector(
({ get }) => get(myAtom, ['a param']).someField
)

const selectorComposition = useAtomSelector(
({ select }) => `${select(helloSelector)}, ${select(worldSelector)}!`
)

const staticVal = useAtomSelector(
({ getInstance }) => getInstance(myAtom).getState().someField
)

const staticValUsingEcosystem = useAtomSelector(
({ ecosystem }) => ecosystem.get(myAtom).someField
)

// passing a selector cache directly:
const cache = ecosystem.selectors.getCache(mySelector) // doesn't subscribe
const value = useAtomSelector(cache) // subscribes

Signature

useAtomSelector = (selectable, ...args?) => result
selectable

Required. An AtomSelector, AtomSelectorConfig object, or a SelectorCache instance.

It's recommended to pass a stable function/object reference whenever possible for best performance.

If an AtomSelector or AtomSelectorConfig object is passed, useAtomSelector() runs the selector and caches the value if it hasn't been cached yet. If the selector has been cached before with the exact params (deep equality), Zedux doesn't run the selector and returns the cached value.

If a SelectorCache is passed, useAtomSelector() simply returns the cached value.

In all cases, useAtomSelector() registers a dynamic dependency on the resolved selector cache - the current React component will reevaluate whenever the selector result changes

args

Required if the selector takes arguments. Must not be passed otherwise.

Selector arguments should always be serializable values (no functions). You can remove this requirement via the complexParams ecosystem config option (not recommended).

Returns

The result of running the selector. If the given selector + args combo has been cached before, useAtomSelector() returns the cached value.

See Also