jotai
Version:
👻 Primitive and flexible state management for React
47 lines (46 loc) • 1.55 kB
JavaScript
'use client';
import { useDebugValue, useEffect, useReducer } from 'react';
import { createContinuablePromise, isPromiseLike, } from './continuablePromise.js';
import { useStore } from './Provider.js';
const createState = (store, atom, value) => [
value,
store,
atom,
(callback) => {
const unsub = store.sub(atom, callback);
let needsRerender = true;
try {
needsRerender = !Object.is(value, store.get(atom));
}
catch {
// Rerender on error.
}
if (needsRerender) {
callback();
}
return unsub;
},
];
export function useAtomValueRaw(atom, options) {
const store = useStore(options);
const [[valueFromReducer, storeFromReducer, atomFromReducer, subscribe], rerender,] = useReducer((prev) => {
const nextValue = store.get(atom);
if (prev[1] === store && prev[2] === atom) {
return Object.is(prev[0], nextValue)
? prev
: [nextValue, store, atom, prev[3]];
}
return createState(store, atom, nextValue);
}, undefined, () => createState(store, atom, store.get(atom)));
let value = valueFromReducer;
if (storeFromReducer !== store || atomFromReducer !== atom) {
rerender();
value = store.get(atom);
}
useEffect(() => subscribe(rerender), [subscribe]);
useDebugValue(value);
if (isPromiseLike(value)) {
return createContinuablePromise(store, value, () => store.get(atom));
}
return value;
}