deno.land / x / jotai@v1.8.4 / src / core / useAtomValue.ts

useAtomValue.ts
نووسراو ببینە
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import { useContext, useDebugValue, useEffect, useReducer } from 'react'import type { Reducer } from 'react'import type { Atom } from './atom'import { getScopeContext } from './contexts'import { COMMIT_ATOM, READ_ATOM, SUBSCRIBE_ATOM } from './store'import type { VersionObject } from './store'import type { ExtractAtomValue } from './typeUtils'
type Scope = NonNullable<Parameters<typeof getScopeContext>[0]>
export function useAtomValue<Value>( atom: Atom<Promise<Value>>, scope?: Scope): Value
export function useAtomValue<Value>( atom: Atom<Value>, scope?: Scope): Awaited<Value>
export function useAtomValue<AtomType extends Atom<any>>( atom: AtomType, scope?: Scope): Awaited<ExtractAtomValue<AtomType>>
export function useAtomValue<Value>(atom: Atom<Value>, scope?: Scope) { const ScopeContext = getScopeContext(scope) const scopeContainer = useContext(ScopeContext) const { s: store, v: versionFromProvider } = scopeContainer
const getAtomValue = (version?: VersionObject) => { // This call to READ_ATOM is the place where derived atoms will actually be // recomputed if needed. const atomState = store[READ_ATOM](atom, version) if (__DEV__ && !atomState.y) { throw new Error('should not be invalidated') } if ('e' in atomState) { throw atomState.e // read error } if ('p' in atomState) { throw atomState.p // read promise } if ('v' in atomState) { return atomState.v as Awaited<Value> } throw new Error('no atom value') }
// Pull the atoms's state from the store into React state. const [[version, valueFromReducer, atomFromReducer], rerenderIfChanged] = useReducer< Reducer< readonly [VersionObject | undefined, Awaited<Value>, Atom<Value>], VersionObject | undefined >, VersionObject | undefined >( (prev, nextVersion) => { const nextValue = getAtomValue(nextVersion) if (Object.is(prev[1], nextValue) && prev[2] === atom) { return prev // bail out } return [nextVersion, nextValue, atom] }, versionFromProvider, (initialVersion) => { const initialValue = getAtomValue(initialVersion) return [initialVersion, initialValue, atom] } )
let value = valueFromReducer if (atomFromReducer !== atom) { rerenderIfChanged(version) value = getAtomValue(version) }
useEffect(() => { const { v: versionFromProvider } = scopeContainer if (versionFromProvider) { store[COMMIT_ATOM](atom, versionFromProvider) } // Call `rerenderIfChanged` whenever this atom is invalidated. Note // that derived atoms may not be recomputed yet. const unsubscribe = store[SUBSCRIBE_ATOM]( atom, rerenderIfChanged, versionFromProvider ) rerenderIfChanged(versionFromProvider) return unsubscribe }, [store, atom, scopeContainer])
useEffect(() => { store[COMMIT_ATOM](atom, version) })
useDebugValue(value) return value}
jotai

Version Info

Tagged at
2 years ago