Skip to content

Commit

Permalink
fix(FetchyeProvider): correct stale data bug (#47)
Browse files Browse the repository at this point in the history
Ensure the selector properly causes a render when the key changes
  • Loading branch information
code-forger committed Jul 9, 2021
1 parent 574ccd3 commit 2ff8c5a
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 3 deletions.
44 changes: 43 additions & 1 deletion packages/fetchye/__tests__/FetchyeProvider.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
*/

import React, { useContext, useEffect } from 'react';
import { render } from '@testing-library/react';
import { act, render } from '@testing-library/react';
import {
FetchyeContext, loadingAction, setAction, deleteAction, errorAction, clearErrorsAction,
// eslint-disable-next-line import/no-unresolved
} from 'fetchye-core';
import PropTypes from 'prop-types';
import FetchyeProvider from '../src/FetchyeProvider';

global.fetch = () => {};
Expand Down Expand Up @@ -130,4 +131,45 @@ describe('FetchyeProvider', () => {
}
`);
});
it('should return a stable response from useFetchyeSelector that changes properly with a changed input', () => {
const initialData = {
data: {
key1: 'val1',
key2: 'val2',
},
loading: {},
errors: {},
};
const captureValue = jest.fn();

const Component = ({ id }) => {
const { useFetchyeSelector } = useContext(FetchyeContext);
const selectedRef = useFetchyeSelector(id);
captureValue(selectedRef.current);
return <fake-element />;
};

Component.propTypes = {
id: PropTypes.string.isRequired,
};

const { rerender } = render(
<FetchyeProvider initialData={initialData}>
<Component id="key1" />
</FetchyeProvider>
);
act(() => {
rerender(
<FetchyeProvider initialData={initialData}>
<Component id="key2" />
</FetchyeProvider>
);
});

// The value will have been captured 3 times.
// The first render causes val1 to be captured.
// The second render causes val1 to be captured again, but queues the effect
// The effect causes a third render that captures val2 as expected
expect(captureValue).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`FetchyeProvider should return a stable response from useFetchyeSelector that changes properly with a changed input 1`] = `
[MockFunction] {
"calls": Array [
Array [
Object {
"data": "val1",
"error": undefined,
"loading": false,
},
],
Array [
Object {
"data": "val1",
"error": undefined,
"loading": false,
},
],
Array [
Object {
"data": "val2",
"error": undefined,
"loading": false,
},
],
],
"results": Array [
Object {
"type": "return",
"value": undefined,
},
Object {
"type": "return",
"value": undefined,
},
Object {
"type": "return",
"value": undefined,
},
],
}
`;
2 changes: 0 additions & 2 deletions packages/fetchye/src/FetchyeProvider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ const makeUseFetchyeSelector = ({
const selectorValue = useRef(initialValue);

useEffect(() => {
selectorValue.current = getCacheByKey(fetchyeState.current, key);

function checkForUpdates() {
const nextValue = getCacheByKey(fetchyeState.current, key);
lastSelectorValue.current = selectorValue.current;
Expand Down

0 comments on commit 2ff8c5a

Please sign in to comment.