diff --git a/docs/integrations/effect.mdx b/docs/integrations/effect.mdx index 24943fc236..7491b63e9c 100644 --- a/docs/integrations/effect.mdx +++ b/docs/integrations/effect.mdx @@ -30,7 +30,7 @@ type EffectFn = ( function atomEffect(effectFn: EffectFn): Atom ``` -**effectFn** (required): A function or async function for listening to state updates with `get` and writing state updates with `set`. The `effectFn` is useful for creating side effects that interact with other Jotai atoms. You can cleanup these side effects by returning a cleanup function. +**effectFn** (required): A function for listening to state updates with `get` and writing state updates with `set`. The `effectFn` is useful for creating side effects that interact with other Jotai atoms. You can cleanup these side effects by returning a cleanup function. ## Usage @@ -218,7 +218,7 @@ Aside from mount events, the effect runs when any of its dependencies change val Example ```js - const asyncEffect = atomEffect((get, set) => { + atomEffect((get, set) => { // updates whenever `anAtom` changes value but not when `anotherAtom` changes value get(anAtom) setTimeout(() => { @@ -232,12 +232,14 @@ Aside from mount events, the effect runs when any of its dependencies change val - **Async:** For effects that return a promise, all atoms accessed with `get` prior to the returned promise resolving are added to the atom's internal dependency map. Atoms that have been watched after the promise has resolved, for instance in a `setTimeout`, are not included in the dependency map. + ⚠️ Use [caution](https://github.com/jotaijs/jotai-effect/discussions/10) when using async effects +
Example ```js - const asyncEffect = atomEffect(async (get, set) => { + atomEffect(async (get, set) => { await new Promise((resolve) => setTimeout(resolve, 1000)) // updates whenever `anAtom` changes value but not when `anotherAtom` changes value get(anAtom) @@ -257,7 +259,7 @@ Aside from mount events, the effect runs when any of its dependencies change val Example ```js - const asyncEffect = atomEffect((get, set) => { + atomEffect((get, set) => { // runs once on atom mount // does not update when `idAtom` changes const unsubscribe = subscribe((value) => { @@ -282,7 +284,7 @@ Aside from mount events, the effect runs when any of its dependencies change val ```js const isEnabledAtom = atom(true) - const asyncEffect = atomEffect((get, set) => { + atomEffect((get, set) => { // if `isEnabledAtom` is true, runs when `isEnabledAtom` or `anAtom` changes value // otherwise runs when `isEnabledAtom` or `anotherAtom` changes value if (get(isEnabledAtom)) { @@ -316,9 +318,11 @@ atomEffects are more appropriate for modeling logic in atoms. They are scoped to the store context rather than the component. This guarantees that a single effect will be used regardless of how many calls they have. -The same guarantee can be achieved with the useEffect hook if you ensure that the useEffect has only actioning one call. +The same guarantee can be achieved with the useEffect hook if you ensure that the useEffect has only one actioning call. + +atomEffects are distinguished from useEffect in a few other ways. The can directly react to atom state changes, are resistent to infinite loops, and can be mounted conditionally. -#### Conclusion +#### It's up to you Both useEffect and atomEffect have their own advantages and applications. Your project’s specific needs and your comfort level should guide your selection. Always lean towards an approach that gives you a smoother, more intuitive development experience. Happy coding!