-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Experimental hooks for useTransition() support (#1572)
Summary: Pull Request resolved: #1572 Expose experimental `useTransition()` support for React 18 by exposing variants of Recoil hooks using a different rendering mode that works with `useTransition()`: * `useRecoilValue_TRANSITION_SUPPORT_UNSTABLE()` * `useRecoilValueLoadable_TRANSITION_SUPPORT_UNSTABLE()` * `useRecoilState_TRANSITION_SUPPORT_UNSTABLE()` Example usage to display previous state while a selector is pending: ``` function QueryResults() { const queryParams = useRecoilValue_TRANSITION_SUPPORT_UNSTABLE(queryParamsAtom); const results = useRecoilValue_TRANSITION_SUPPORT_UNSTABLE(myQuerySelector(queryParams)); return results; } function MyApp() { const [queryParams, setQueryParams] = useRecoilState_TRANSITION_SUPPORT_UNSTABLE(queryParamsAtom); const [inTransition, startTransition] = useTransition(); return ( <div> {inTransition ? <div>[Loading new results...]</div> : ''} Results: <React.Suspense><QueryResults /></React.Suspense> <button onClick={() => { startTransition(() => { setQueryParams(...new params...); }); } > New Query </button> </div> ); } ``` Reviewed By: habond Differential Revision: D33812933 fbshipit-source-id: 1c4c80a6d6acfe1626dc815abf6358a02a0d6f5f
- Loading branch information
1 parent
15af2a2
commit 708fcfe
Showing
10 changed files
with
517 additions
and
24 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
148 changes: 148 additions & 0 deletions
148
packages/recoil/hooks/__tests__/Recoil_Hooks_TRANSITION_SUPPORT_UNSTABLE-test.js
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,148 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* @emails oncall+recoil | ||
* @flow strict-local | ||
* @format | ||
*/ | ||
'use strict'; | ||
|
||
// Sanity tests for *_TRANSITION_SUPPORT_UNSTABLE() hooks. The actual tests | ||
// for useTransition() support are in Recoil_useTransition-test.js | ||
|
||
const { | ||
getRecoilTestFn, | ||
} = require('recoil-shared/__test_utils__/Recoil_TestingUtils'); | ||
|
||
let React, | ||
act, | ||
selector, | ||
stringAtom, | ||
asyncSelector, | ||
flushPromisesAndTimers, | ||
renderElements, | ||
useRecoilState, | ||
useRecoilState_TRANSITION_SUPPORT_UNSTABLE, | ||
useRecoilValue, | ||
useRecoilValue_TRANSITION_SUPPORT_UNSTABLE, | ||
useRecoilValueLoadable, | ||
useRecoilValueLoadable_TRANSITION_SUPPORT_UNSTABLE, | ||
useSetRecoilState, | ||
reactMode; | ||
|
||
const testRecoil = getRecoilTestFn(() => { | ||
React = require('react'); | ||
({act} = require('ReactTestUtils')); | ||
|
||
selector = require('../../recoil_values/Recoil_selector'); | ||
({ | ||
stringAtom, | ||
asyncSelector, | ||
flushPromisesAndTimers, | ||
renderElements, | ||
} = require('recoil-shared/__test_utils__/Recoil_TestingUtils')); | ||
({reactMode} = require('../../core/Recoil_ReactMode')); | ||
({ | ||
useRecoilState, | ||
useRecoilState_TRANSITION_SUPPORT_UNSTABLE, | ||
useRecoilValue, | ||
useRecoilValue_TRANSITION_SUPPORT_UNSTABLE, | ||
useRecoilValueLoadable, | ||
useRecoilValueLoadable_TRANSITION_SUPPORT_UNSTABLE, | ||
useSetRecoilState, | ||
} = require('../Recoil_Hooks')); | ||
}); | ||
|
||
testRecoil('useRecoilValue_TRANSITION_SUPPORT_UNSTABLE', async () => { | ||
if (!reactMode().early) { | ||
return; | ||
} | ||
const myAtom = stringAtom(); | ||
const [mySelector, resolve] = asyncSelector(); | ||
let setAtom; | ||
function Component() { | ||
setAtom = useSetRecoilState(myAtom); | ||
return [ | ||
useRecoilValue(myAtom), | ||
useRecoilValue_TRANSITION_SUPPORT_UNSTABLE(myAtom), | ||
useRecoilValue(mySelector), | ||
useRecoilValue_TRANSITION_SUPPORT_UNSTABLE(mySelector), | ||
].join(' '); | ||
} | ||
const c = renderElements(<Component />); | ||
expect(c.textContent).toBe('loading'); | ||
|
||
act(() => resolve('RESOLVE')); | ||
await flushPromisesAndTimers(); | ||
expect(c.textContent).toBe('DEFAULT DEFAULT RESOLVE RESOLVE'); | ||
|
||
act(() => setAtom('SET')); | ||
expect(c.textContent).toBe('SET SET RESOLVE RESOLVE'); | ||
}); | ||
|
||
testRecoil('useRecoilValueLoadable_TRANSITION_SUPPORT_UNSTABLE', async () => { | ||
if (!reactMode().early) { | ||
return; | ||
} | ||
const myAtom = stringAtom(); | ||
const [mySelector, resolve] = asyncSelector(); | ||
let setAtom; | ||
function Component() { | ||
setAtom = useSetRecoilState(myAtom); | ||
return [ | ||
useRecoilValueLoadable(myAtom).getValue(), | ||
useRecoilValueLoadable_TRANSITION_SUPPORT_UNSTABLE(myAtom).getValue(), | ||
useRecoilValueLoadable(mySelector).getValue(), | ||
useRecoilValueLoadable_TRANSITION_SUPPORT_UNSTABLE(mySelector).getValue(), | ||
].join(' '); | ||
} | ||
const c = renderElements(<Component />); | ||
expect(c.textContent).toBe('loading'); | ||
|
||
act(() => resolve('RESOLVE')); | ||
await flushPromisesAndTimers(); | ||
expect(c.textContent).toBe('DEFAULT DEFAULT RESOLVE RESOLVE'); | ||
|
||
act(() => setAtom('SET')); | ||
expect(c.textContent).toBe('SET SET RESOLVE RESOLVE'); | ||
}); | ||
|
||
testRecoil('useRecoilState_TRANSITION_SUPPORT_UNSTABLE', async () => { | ||
if (!reactMode().early) { | ||
return; | ||
} | ||
const myAtom = stringAtom(); | ||
const [myAsyncSelector, resolve] = asyncSelector(); | ||
const mySelector = selector({ | ||
key: 'useRecoilState_TRANSITION_SUPPORT_UNSTABLE selector', | ||
get: () => myAsyncSelector, | ||
set: ({set}, newValue) => set(myAtom, newValue), | ||
}); | ||
let setAtom, setSelector; | ||
function Component() { | ||
const [v1] = useRecoilState(myAtom); | ||
const [v2, setAtomValue] = | ||
useRecoilState_TRANSITION_SUPPORT_UNSTABLE(myAtom); | ||
setAtom = setAtomValue; | ||
const [v3] = useRecoilState(mySelector); | ||
const [v4, setSelectorValue] = | ||
useRecoilState_TRANSITION_SUPPORT_UNSTABLE(mySelector); | ||
setSelector = setSelectorValue; | ||
return [v1, v2, v3, v4].join(' '); | ||
} | ||
const c = renderElements(<Component />); | ||
expect(c.textContent).toBe('loading'); | ||
|
||
act(() => resolve('RESOLVE')); | ||
await flushPromisesAndTimers(); | ||
expect(c.textContent).toBe('DEFAULT DEFAULT RESOLVE RESOLVE'); | ||
|
||
act(() => setAtom('SET')); | ||
expect(c.textContent).toBe('SET SET RESOLVE RESOLVE'); | ||
|
||
act(() => setSelector('SETS')); | ||
expect(c.textContent).toBe('SETS SETS RESOLVE RESOLVE'); | ||
}); |
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.