diff --git a/Changelog.md b/Changelog.md index 655e8daa0b..0ec63597f1 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,6 +11,10 @@ component, after an error was received, variables were adjusted, and then the good data was fetched.
[@MerzDaniel](https://github.com/MerzDaniel) in [#2718](https://github.com/apollographql/react-apollo/pull/2718) +- Fixed an issue that prevented `Query` component updates from firing (under + certain circumstances) due to the internal `lastResult` value (that's used + to help prevent unnecessary re-renders) not being updated.
+ [@Glennrs](https://github.com/Glennrs) in [#2840](https://github.com/apollographql/react-apollo/pull/2840) ### Improvements diff --git a/src/Query.tsx b/src/Query.tsx index 42280f7948..6379f868d9 100644 --- a/src/Query.tsx +++ b/src/Query.tsx @@ -342,6 +342,9 @@ export default class Query extends } initial = undefined; + if (this.lastResult) { + this.lastResult = this.queryObservable!.getLastResult(); + } this.updateCurrentData(); }, error: error => { diff --git a/test/client/Query.test.tsx b/test/client/Query.test.tsx index 9e39a5e7e0..3ed8c3c82b 100644 --- a/test/client/Query.test.tsx +++ b/test/client/Query.test.tsx @@ -1232,6 +1232,115 @@ describe('Query component', () => { , ); }); + + it( + 'should update if a manual `refetch` is triggered after a state change', + done => { + const query: DocumentNode = gql` + query { + allPeople { + people { + name + } + } + } + `; + + const data1 = { allPeople: { people: [{ name: 'Luke Skywalker' }] } }; + + const link = mockSingleLink( + { + request: { query }, + result: { data: data1 }, + }, + { + request: { query }, + result: { data: data1 }, + }, + { + request: { query }, + result: { data: data1 }, + }, + ); + + const client = new ApolloClient({ + link, + cache: new Cache({ addTypename: false }), + }); + + let count = 0; + + class SomeComponent extends React.Component { + constructor(props: any) { + super(props); + this.state = { + open: false, + }; + this.toggle = this.toggle.bind(this); + } + + toggle() { + this.setState((prevState: any) => ({ + open: !prevState.open, + })); + } + + render() { + const { open } = this.state as any; + return ( + + {(props: any) => { + try { + switch (count) { + case 0: + // Loading first response + expect(props.loading).toBe(true); + expect(open).toBe(false); + break; + case 1: + // First response loaded, change state value + expect(stripSymbols(props.data)).toEqual(data1); + expect(open).toBe(false); + setTimeout(() => { + this.toggle(); + }, 0); + break; + case 2: + // State value changed, fire a refetch + expect(open).toBe(true); + setTimeout(() => { + props.refetch(); + }, 0); + break; + case 3: + // Second response received, fire another refetch + expect(stripSymbols(props.data)).toEqual(data1); + setTimeout(() => { + props.refetch(); + }, 0); + break; + case 4: + // Third response received + expect(stripSymbols(props.data)).toEqual(data1); + done(); + break; + default: + done.fail('Unknown count'); + } + count += 1; + } catch (error) { + done.fail(error); + } + return null; + }} + + ); + } + } + + wrapper = mount(); + } + ); }); it('should error if the query changes type to a subscription', done => {