diff --git a/docs/advanced-recipes/atom-creators.mdx b/docs/advanced-recipes/atom-creators.mdx index 5117c8ff52..269fa4950a 100644 --- a/docs/advanced-recipes/atom-creators.mdx +++ b/docs/advanced-recipes/atom-creators.mdx @@ -155,3 +155,62 @@ const StylePreview = () => { ) } ``` + +## atomWithRefresh + +> `atomWithRefresh` creates a derived atom that can be force-refreshed, by using +> the update function. + +This is helpful when you need to refresh asynchronous data after performing a +side effect. + +It can also be used to implement "pull to refresh" functionality. + +```ts +import { atom, Getter } from 'jotai' + +export function atomWithRefresh(fn: (get: Getter) => T) { + const refreshCounter = atom(0) + + return atom( + (get) => { + get(refreshCounter) + return fn(get) + }, + (_, set) => set(refreshCounter, (i) => i + 1) + ) +} +``` + +Here's how you'd use it to implement an refreshable source of data: + +```ts +import { atomWithRefresh } from 'XXX' + +const postsAtom = atomWithRefresh((get) => + fetch('https://jsonplaceholder.typicode.com/posts').then((r) => r.json()) +) +``` + +In a component: + +```ts +const PostsList = () => { + const [posts, refreshPosts] = useAtom(postsAtom) + + return ( +
+ + + {/* Clicking this button will re-fetch the posts */} + +
+ ) +} +```