Skip to content

Instantly share code, notes, and snippets.

@debugtheworldbot
Last active September 15, 2023 06:10
Show Gist options
  • Select an option

  • Save debugtheworldbot/42cbb7dea3a41b2622aeeb052a69e90b to your computer and use it in GitHub Desktop.

Select an option

Save debugtheworldbot/42cbb7dea3a41b2622aeeb052a69e90b to your computer and use it in GitHub Desktop.
minimal jotai implementation
import { useSyncExternalStore } from 'react'
type CB<T> = (v: T) => void
export type Atom<V> = {
get: () => V
set: (v: V | ((oldV: V) => V)) => V
subscribe: (cb: CB<V>) => () => void
}
export function atom<AtomValue>(value: AtomValue): Atom<AtomValue> {
const subscribers = new Set<(value: AtomValue) => void>()
return {
get: () => {
return value
},
set: newValue => {
let result: AtomValue
if (newValue instanceof Function) {
result = newValue(value)
} else {
result = newValue
}
value = result
subscribers.forEach(cb => cb(result))
return result
},
subscribe: callback => {
subscribers.add(callback)
return () => {
subscribers.delete(callback)
}
}
}
}
export function useAtom<AtomValue>(
atom: Atom<AtomValue>
): [AtomValue, Atom<AtomValue>['set']] {
return [useSyncExternalStore(atom.subscribe, atom.get), atom.set]
}
export function useAtomValue<V>(atom: Atom<V>) {
return useAtom(atom)[0]
}
export function useSetAtom<V>(atom: Atom<V>) {
return useAtom(atom)[1]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment