Skip to content

Commit

Permalink
Test onSet() is called when atom initialized via snapshot (facebookex…
Browse files Browse the repository at this point in the history
…perimental#1519)

Summary:
Pull Request resolved: facebookexperimental#1519

Test that `onSet()` is called and `setSelf()` works when atoms are initialized first via Snapshot and then used from hooks in a `<RecoilRoot>`.  This includes when initializing atoms via `initializeState` prop in `<RecoilRoot>` which uses a Snapshot.  Also make sure the "current" value provided in the updater form of `setSelf()` reflects the current initialized value.

Reviewed By: habond

Differential Revision: D33372676

fbshipit-source-id: 069d89bbfe0d0c1b1a3a31508a5b7e3f1e2de278
  • Loading branch information
drarmstr authored and facebook-github-bot committed Jan 5, 2022
1 parent 78f1ab8 commit 56f8115
Show file tree
Hide file tree
Showing 6 changed files with 257 additions and 167 deletions.
8 changes: 5 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@
### Other Fixes and Optimizations
- Only clone the current snapshot for callbacks if the callback actually uses it. (#1501)
- Fix transitive selector refresh for some cases (#1409)
- Run atom effects when atoms are initialized from a set during a transaction from `useRecoilTransaction_UNSTABLE()` (#1466)
- Unsubscribe `onSet()` handlers in atom effects when atoms are cleaned up. (#1509)
- Atom effects are cleaned up when initialized by a Snapshot which is released. (#1511)
- Atom Effects
- Run atom effects when atoms are initialized from a set during a transaction from `useRecoilTransaction_UNSTABLE()` (#1466)
- Atom effects are cleaned up when initialized by a Snapshot which is released. (#1511)
- Unsubscribe `onSet()` handlers in atom effects when atoms are cleaned up. (#1509)
- Call `onSet()` when atoms are initialized with `<RecoilRoot initializeState={...} >` (#1519, #1511)
- Avoid extra re-renders in some cases when a component uses a different atom/selector. (#825)
- `<RecoilRoot>` will only call `initializeState()` once during the initial render. (#1372)

Expand Down
48 changes: 40 additions & 8 deletions packages/recoil/core/__tests__/Recoil_RecoilRoot-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,14 @@ describe('initializeState', () => {
effects_UNSTABLE: [
({setSelf}) => {
effectRan++;
setSelf(current => {
// Effects are run first.
expect(current).toEqual('DEFAULT');
return 'EFFECT';
});
setSelf('EFFECT');
},
],
});

function initializeState({set}) {
set(myAtom, current => {
// Effects are run first, initializeState() takes precedence
// Effects are run first
expect(current).toEqual('EFFECT');
return 'INITIALIZE';
});
Expand All @@ -136,15 +132,51 @@ describe('initializeState', () => {
expect(container1.textContent).toEqual('NO READ');
expect(effectRan).toEqual(strictMode ? (concurrentMode ? 4 : 3) : 2);

effectRan = 0;
const container2 = renderElements(
<RecoilRoot initializeState={initializeState}>
<ReadsAtom atom={myAtom} />
</RecoilRoot>,
);

// Effects are run first, initializeState() takes precedence
// Effects takes precedence
expect(container2.textContent).toEqual('"EFFECT"');
expect(effectRan).toEqual(strictMode ? (concurrentMode ? 8 : 6) : 4);
expect(effectRan).toEqual(strictMode ? (concurrentMode ? 4 : 3) : 2);
},
);

testRecoil(
'onSet() called when atom initialized with initializeState',
() => {
const setValues = [];
const myAtom = atom({
key: 'RecoilRoot - initializeState - onSet',
default: 0,
effects_UNSTABLE: [
({onSet, setSelf}) => {
onSet(value => {
setValues.push(value);
// Confirm setSelf() works when initialized with initializeState
setSelf(value + 1);
});
},
],
});

const [MyAtom, setAtom] = componentThatReadsAndWritesAtom(myAtom);

const c = renderElements(
<RecoilRoot initializeState={({set}) => set(myAtom, 1)}>
<MyAtom />
</RecoilRoot>,
);

expect(c.textContent).toBe('1');
expect(setValues).toEqual([]);

act(() => setAtom(2));
expect(setValues).toEqual([2]);
expect(c.textContent).toBe('3');
},
);

Expand Down
Loading

0 comments on commit 56f8115

Please sign in to comment.