forked from pmndrs/jotai
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core): Move useAtomValue and useSetAtom to core (pmndrs#989)
* Rename useUpdateAtom to useSetAtom Move useAtomValue and useSetAtom to core * Fix test * Move exports, delete files * Move impl to respective hooks * Do not export ResolveType * Cleanup after merge * Changes after review * refactor, add comments * empty commit * empty commit Co-authored-by: daishi <[email protected]>
- Loading branch information
Showing
19 changed files
with
173 additions
and
180 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { | ||
useCallback, | ||
useContext, | ||
useDebugValue, | ||
useEffect, | ||
useReducer, | ||
} from 'react' | ||
import type { Reducer } from 'react' | ||
import type { Atom, Scope } from './atom' | ||
import { getScopeContext } from './contexts' | ||
import { COMMIT_ATOM, READ_ATOM, SUBSCRIBE_ATOM } from './store' | ||
import type { VersionObject } from './store' | ||
|
||
type ResolveType<T> = T extends Promise<infer V> ? V : T | ||
|
||
export function useAtomValue<Value>( | ||
atom: Atom<Value>, | ||
scope?: Scope | ||
): ResolveType<Value> { | ||
const ScopeContext = getScopeContext(scope) | ||
const { s: store } = useContext(ScopeContext) | ||
|
||
const getAtomValue = useCallback( | ||
(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 ('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 ResolveType<Value> | ||
} | ||
throw new Error('no atom value') | ||
}, | ||
[store, atom] | ||
) | ||
|
||
// Pull the atoms's state from the store into React state. | ||
const [[version, value, atomFromUseReducer], rerenderIfChanged] = useReducer< | ||
Reducer< | ||
readonly [VersionObject | undefined, ResolveType<Value>, Atom<Value>], | ||
VersionObject | undefined | ||
>, | ||
undefined | ||
>( | ||
useCallback( | ||
(prev, nextVersion) => { | ||
const nextValue = getAtomValue(nextVersion) | ||
if (Object.is(prev[1], nextValue) && prev[2] === atom) { | ||
return prev // bail out | ||
} | ||
return [nextVersion, nextValue, atom] | ||
}, | ||
[getAtomValue, atom] | ||
), | ||
undefined, | ||
() => { | ||
// NOTE should/could branch on mount? | ||
const initialVersion = undefined | ||
const initialValue = getAtomValue(initialVersion) | ||
return [initialVersion, initialValue, atom] | ||
} | ||
) | ||
|
||
if (atomFromUseReducer !== atom) { | ||
rerenderIfChanged(undefined) | ||
} | ||
|
||
useEffect(() => { | ||
// Call `rerenderIfChanged` whenever this atom is invalidated. Note | ||
// that derived atoms may not be recomputed yet. | ||
const unsubscribe = store[SUBSCRIBE_ATOM](atom, rerenderIfChanged) | ||
rerenderIfChanged(undefined) | ||
return unsubscribe | ||
}, [store, atom]) | ||
|
||
useEffect(() => { | ||
store[COMMIT_ATOM](atom, version) | ||
}) | ||
|
||
useDebugValue(value) | ||
return value | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { useCallback, useContext } from 'react' | ||
import type { Scope, SetAtom, WritableAtom } from '../core/atom' | ||
import { WRITE_ATOM } from '../core/store' | ||
import type { VersionObject } from '../core/store' | ||
import { getScopeContext } from './contexts' | ||
|
||
export function useSetAtom<Value, Update, Result extends void | Promise<void>>( | ||
atom: WritableAtom<Value, Update, Result>, | ||
scope?: Scope | ||
): SetAtom<Update, Result> { | ||
const ScopeContext = getScopeContext(scope) | ||
const { s: store, w: versionedWrite } = useContext(ScopeContext) | ||
const setAtom = useCallback( | ||
(update: Update) => { | ||
if ( | ||
!('write' in atom) && | ||
typeof process === 'object' && | ||
process.env.NODE_ENV !== 'production' | ||
) { | ||
// useAtom can pass non writable atom with wrong type assertion, | ||
// so we should check here. | ||
throw new Error('not writable atom') | ||
} | ||
const write = (version?: VersionObject) => | ||
store[WRITE_ATOM](atom, update, version) | ||
return versionedWrite ? versionedWrite(write) : write() | ||
}, | ||
[store, versionedWrite, atom] | ||
) | ||
return setAtom as SetAtom<Update, Result> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.