AtomGetters
An object that provides several functions for working with atoms.
{
ecosystem, get, getInstance, select
}
You'll find this object in the following places:
- The first parameter to ion state factories.
- The first parameter to AtomSelectors.
injectAtomGetters()
returns one.- Ecosystems themselves are AtomGetters objects, minus the
ecosystem
property.
When called synchronously during atom or selector evaluation, get
, getInstance
, and select
will register graph dependencies on resolved atom instances and SelectorCaches. Thus:
get()
is similar toinjectAtomValue()
.getInstance()
is similar toinjectAtomInstance()
.select()
is similar toinjectAtomSelector()
.
The ecosystem's AtomGetters (ecosystem.get()
, ecosystem.getInstance()
, and ecosystem.select()
) however never register graph dependencies.
The AtomGetters are not injectors. This means they can be called in loops or if statements or even asynchronously.
When called asynchronously, AtomGetters don't register graph dependencies; they simply return the expected values. Thus:
get
becomes an alias forecosystem.get()
.getInstance
becomes an alias forecosystem.getInstance()
.select
becomes an alias forecosystem.select()
.
Definition
- Simplified
- TypeScript
atomGetters = { ecosystem, get, getInstance, select }
interface AtomGetters {
ecosystem: Ecosystem
get<A extends AnyAtomTemplate>(
template: A,
params: AtomParamsType<A>
): AtomStateType<A>
get<A extends AnyAtomTemplate>(
template: ParamlessTemplate<A>
): AtomStateType<A>
get<I extends AtomInstance>(instance: I): AtomStateType<I>
getInstance<A extends AnyAtomTemplate>(
template: A,
params: AtomParamsType<A>
): AtomInstanceType<A>
getInstance<A extends AnyAtomTemplate>(
template: ParamlessTemplate<A>
): AtomInstanceType<A>
getInstance<I extends AtomInstance>(instance: I): I
select<T, Args extends any[]>(
atomSelector: AtomSelectorOrConfig<T, Args>,
...args: Args
): T
}
A reference to the ecosystem the current atom or selector was created in.
The ecosystem is called an "AtomGetter", but it's really an AtomGetter object containing its own AtomGetters. Ecosystems are the only AtomGetters objects that don't have an ecosystem
property (they don't need it obviously).
Use this AtomGetter when you want to specifically avoid registering graph dependencies.
const dynamicVal = get(val) // registers a dependency
const staticVal = ecosystem.get(val) // doesn't register anything
The ecosystem also has additional methods for getting atom instances:
// returns the first matching atom instance only if one exists already
// (unlike ecosystem.getInstance() which creates the instance if it doesn't exist):
ecosystem.find(myAtom, [param1, param2])
// returns all matching atom instances. Also doesn't create any instances:
ecosystem.findAll(myAtom, [param1, param2])
Both ecosystem.find()
and ecosystem.findAll()
can take a fuzzy search string to find instances whose ids contain the passed string (case-insensitive).
On the ecosystem, you also have access to the .selectors
property for full manual control over cached selectors.
A function that returns the current state of an atom instance's store. Pass either an atom template and its params (if the atom takes params) or an atom instance directly.
value = get(myAtom)
value = get(myAtom, [param1, param2])
value = get(myAtomInstance)
When an atom template is passed, get()
creates the instance if it doesn't exist yet, registers a dynamic graph dependency on the instance, and returns its initial value.
When an instance is passed, get()
registers a dynamic graph dependency on that instance and returns its current value.
When called asynchronously (after the current atom instance or selector finishes evaluating), get()
doesn't register any graph dependencies. Other than that, it behaves the same as when called synchronously during evaluation.
Use ecosystem.find().getState()
to get a value only if the instance already exists. Note however that the ecosystem's getters don't register graph dependencies. To weakly register a dependency, use the following pattern:
const instance = ecosystem.find(myAtom, [param1, param2])
const val = instance ? get(instance) : defaultVal
A function that returns the atom instance for the given atom template + params combo. Pass either an atom template and its params (if the atom takes params) or an atom instance directly.
instance = getInstance(myAtom)
instance = getInstance(myAtom, ['param 1', 'param 2'])
instance = getInstance(myAtomInstance)
When an atom template is passed, getInstance()
creates the instance if it doesn't exist yet, registers a static graph dependency on the instance, and returns it.
When an instance is passed, getInstance()
registers a static graph dependency on that instance and returns it as-is.
When called asynchronously (after the current atom instance or selector finishes evaluating), getInstance()
doesn't register any graph dependencies. Other than that, it behaves the same.
Use ecosystem.find()
to get an instance only if it already exists. Note however that the ecosystem's getters don't register graph dependencies. To weakly register a static dependency, use the following pattern:
const maybeInstance = ecosystem.find(myAtom, [param1, param2])
const instance = maybeInstance ? getInstance(maybeInstance) : undefined
A function that returns an atom selector's value. Pass an atom selector, an AtomSelectorConfig object, or a SelectorCache instance.
value = select(atomSelector, arg1, arg2)
value = select(atomSelectorConfig, arg1, arg2)
value = select(aSelectorCache)
If an atom selector or AtomSelectorConfig object is passed and the selector takes arguments, those are required. Note that unlike get()
and getInstance()
, select
's args are spread into the function call, instead of being passed as an array.
If an atom selector or AtomSelectorConfig object is passed, select()
runs and caches the atom selector if it hasn't been cached yet and returns the result. This is unlike ecosystem.select() which never caches the selector (though it will return the cached value if one exists).
If a SelectorCache is passed, select()
registers a dynamic dependency on the cache and returns the cache's current result.
When called asynchronously (after the current atom instance or selector finishes evaluating), select()
doesn't register any graph dependencies. Other than that, it behaves the same as when called synchronously during evaluation.
Use ecosystem.selectors.find(mySelector)?.result
to get the selector's cached value only if it has been cached already. Note however that this doesn't register any graph dependencies. To weakly register a dynamic dependency on a selector, use the following pattern:
const cache = ecosystem.selectors.find(mySelector)
const val = cache ? select(cache) : defaultVal
For best cache performance, pass a stable atom selector function (or AtomSelectorConfig object) reference. Inline selectors work too, but will make Zedux do extra work on reevaluations when the selector reference changes. This is usually fine, but be mindful of it in larger apps.
Stable references can also make your graph look better, since Zedux defaults to using the selector function's name as part of its id
. Unless you specifically make your inline selectors named functions (not common), they won't have a name, causing Zedux to generate a random id.