Skip to main content

AtomSelectorConfig

Everywhere Zedux accepts an AtomSelector, it also accepts an AtomSelectorConfig object. This object has a required selector field and a few optional fields used to configure the selector.

It is recommended to set the name field for optimal debugging when viewing the atom graph since Zedux can't derive a useful name from AtomSelectorConfig objects like it can with named AtomSelector functions. You can also make the selector field a named function instead of using an anonymous function.

Examples

Live Sandbox
12345678910111213141516171819
const counterAtom = atom('counter', 0)

function CountBy5() {
const { setState } = useAtomInstance(counterAtom)
const counter = useAtomSelector({
name: 'getCounter',
resultsComparator: newCount => newCount % 5,
selector: ({ get }) => get(counterAtom),
})

return (
<>
<div>Value: {counter}</div>
<button onClick={() => setState(state => state + 1)}>
Increment (click me 5 times)
</button>
</>
)
}
tip

AtomSelectors sometimes have config that's inherent to how they operate. Rather than exporting the selector function and requiring consumers to specify the config, export the config object itself (tightly coupling the selector to its mandatory config):

// instead of:
export const getUserSnapshot = ({ get }: AtomGetters) => get(currentUserAtom)
...
select({
resultsComparator: (a, b) => a.id === b.id,
selector: getUserSnapshot,
})

// do:
export const getUserSnapshot = {
name: 'getUserSnapshot', // recommended if using an anonymous function
resultsComparator: (a, b) => a.id === b.id,
selector: ({ get }) => get(currentUserAtom)
}
...
select(getUserSnapshot)

Miscellaneous:

// Inline:
useAtomSelector({
argsComparator: (newVal, oldVal) => Math.abs(newVal - oldVal) > 5,
name: 'timesTwo',
selector: ({ get }: AtomGetters) => get(myAtom) * 2,
})

// Extracted:
const timesTwo = {
argsComparator: (newVal, oldVal) => Math.abs(newVal - oldVal) > 5,
name: 'timesTwo',
selector: ({ get }) => get(myAtom) * 2,
}
useAtomSelector(timesTwo)

// With arguments:
const timesTwoPlusWhatever = {
argsComparator: (newVal, oldVal) => Math.abs(newVal - oldVal) > 5,
name: 'timesTwo',
selector: ({ get }, whatever: number) => get(myAtom) * 2 + whatever,
}
useAtomSelector(timesTwoPlusWhatever, 3)

Definition

atomSelectorConfig = { argsComparator?, name?, resultsComparator?, selector }
argsComparator

Important! This config option is only respected in useAtomSelector(). It is ignored in all other AtomSelector-related APIs. This is because selectors are given completely different cache entries when different args are passed. However useAtomSelector() does some special optimizations. Regardless, because of this limitation, this config option is rarely useful.

Optional. A function. Signature:

(newArgs, oldArgs) => areEqual

Accepts two arrays - the list of arguments most recently passed and the list of arguments passed previously.

Return true if useAtomSelector() should consider both lists the "same", preventing the selector from reevaluating. Return false to force the selector to reevaluate.

This function is only called after the selector has already run once (otherwise there wouldn't be any oldArgs).

name

Optional. A string.

It is highly recommended to pass this when passing an anonymous function as the selector.

Zedux uses this name to create the node's key in the graph. For your debugging pleasure, always try to make sure selectors are named functions or specify this config option.

resultsComparator

Optional. A function. Signature:

(newResult, oldResult) => areEqual

Accepts the previously-cached result of running this selector and the new result that Zedux is about to cache.

Return true if Zedux should consider both results equal, preventing the cache from updating and all dependents from reevaluating. Return false to force all dependents to reevaluate.

This function is only called after the selector has already run once (otherwise there wouldn't be any oldResult).

selector

Required. The actual AtomSelector function you're configuring.

If passing an anonymous function, it's recommended to also specify the name property.

See Also