1- import { useCallback , useContext , useDebugValue , useEffect } from 'react'
1+ import {
2+ useCallback ,
3+ useContext ,
4+ useDebugValue ,
5+ useEffect ,
6+ useReducer ,
7+ } from 'react'
28import type { Atom , Scope , SetAtom , WritableAtom } from './atom'
39import { getScopeContext } from './contexts'
410import { FLUSH_PENDING , READ_ATOM , SUBSCRIBE_ATOM , WRITE_ATOM } from './store'
5- import type { Store } from './store'
6- import { useMutableSource } from './useMutableSource'
711
812const isWritable = < Value , Update > (
913 atom : Atom < Value > | WritableAtom < Value , Update >
@@ -41,32 +45,6 @@ export function useAtom<Value, Update>(
4145 atom : Atom < Value > | WritableAtom < Value , Update > ,
4246 scope ?: Scope
4347) {
44- const getAtomValue = useCallback (
45- ( store : Store ) => {
46- const atomState = store [ READ_ATOM ] ( atom )
47- if ( atomState . e ) {
48- throw atomState . e // read error
49- }
50- if ( atomState . p ) {
51- throw atomState . p // read promise
52- }
53- if ( atomState . w ) {
54- throw atomState . w // write promise
55- }
56- if ( 'v' in atomState ) {
57- return atomState . v as Value
58- }
59- throw new Error ( 'no atom value' )
60- } ,
61- [ atom ]
62- )
63-
64- const subscribe = useCallback (
65- ( store : Store , callback : ( ) => void ) =>
66- store [ SUBSCRIBE_ATOM ] ( atom , callback ) ,
67- [ atom ]
68- )
69-
7048 if ( 'scope' in atom ) {
7149 console . warn (
7250 'atom.scope is deprecated. Please do useAtom(atom, scope) instead.'
@@ -75,8 +53,33 @@ export function useAtom<Value, Update>(
7553 }
7654
7755 const ScopeContext = getScopeContext ( scope )
78- const [ store , mutableSource ] = useContext ( ScopeContext )
79- const value = useMutableSource ( mutableSource , getAtomValue , subscribe )
56+ const [ store ] = useContext ( ScopeContext )
57+
58+ const getAtomValue = useCallback ( ( ) => {
59+ const atomState = store [ READ_ATOM ] ( atom )
60+ if ( atomState . e ) {
61+ throw atomState . e // read error
62+ }
63+ if ( atomState . p ) {
64+ throw atomState . p // read promise
65+ }
66+ if ( atomState . w ) {
67+ throw atomState . w // write promise
68+ }
69+ if ( 'v' in atomState ) {
70+ return atomState . v as Value
71+ }
72+ throw new Error ( 'no atom value' )
73+ } , [ store , atom ] )
74+
75+ const [ value , forceUpdate ] = useReducer ( getAtomValue , undefined , getAtomValue )
76+
77+ useEffect ( ( ) => {
78+ const unsubscribe = store [ SUBSCRIBE_ATOM ] ( atom , forceUpdate )
79+ forceUpdate ( )
80+ return unsubscribe
81+ } , [ store , atom ] )
82+
8083 useEffect ( ( ) => {
8184 store [ FLUSH_PENDING ] ( )
8285 } )
0 commit comments