diff --git a/src/react/useAtomValue.ts b/src/react/useAtomValue.ts index 6f737bacf7..bed632a2c4 100644 --- a/src/react/useAtomValue.ts +++ b/src/react/useAtomValue.ts @@ -102,22 +102,25 @@ const createContinuablePromise = ( type Options = Parameters[0] & { delay?: number + unstable_defaultUse?: boolean unstable_promiseStatus?: boolean } -export function useAtomValue( +export function useAtomValue( atom: Atom, - options?: Options, -): Awaited - -export function useAtomValue>( - atom: AtomType, - options?: Options, -): Awaited> + options?: O, +): O extends { unstable_defaultUse: true } ? Awaited : Value +export function useAtomValue( + atom: Atom, + options?: O, +): O extends { unstable_defaultUse: true } ? Awaited : Value export function useAtomValue(atom: Atom, options?: Options) { - const { delay, unstable_promiseStatus: promiseStatus = !React.use } = - options || {} + const { + delay, + unstable_promiseStatus: promiseStatus = !React.use, + unstable_defaultUse = true, + } = options || {} const store = useStore(options) const [[valueFromReducer, storeFromReducer, atomFromReducer], rerender] = @@ -174,7 +177,7 @@ export function useAtomValue(atom: Atom, options?: Options) { if (promiseStatus) { attachPromiseStatus(promise) } - return use(promise) + return unstable_defaultUse ? use(promise) : promise } return value as Awaited } diff --git a/tests/react/useAtomValue.test.tsx b/tests/react/useAtomValue.test.tsx index 0147f75567..7a7c64ece5 100644 --- a/tests/react/useAtomValue.test.tsx +++ b/tests/react/useAtomValue.test.tsx @@ -1,8 +1,8 @@ -import { Component, StrictMode, Suspense } from 'react' +import { Component, StrictMode, Suspense, use } from 'react' import type { ReactNode } from 'react' import { act, render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { expect, it } from 'vitest' +import { expect, expectTypeOf, it } from 'vitest' import { useAtomValue, useSetAtom } from 'jotai/react' import { atom } from 'jotai/vanilla' @@ -120,3 +120,24 @@ it('useAtomValue with atom returning object', async () => { expect(await screen.findByText('obj: 1,2')).toBeInTheDocument() }) + +it('useAtomValue with unstable_defaultUse', async () => { + const numberAtom = atom(Promise.resolve(1 as const)) + + const ObjComponent = () => { + const value = useAtomValue(numberAtom, { unstable_defaultUse: false }) + expectTypeOf(value).toEqualTypeOf>() + + return
number: {use(value)}
+ } + + await act(() => + render( + + + , + ), + ) + + expect(await screen.findByText('number: 1')).toBeInTheDocument() +})