diff --git a/__tests__/usePreloadQuery-test.tsx b/__tests__/usePreloadQuery-test.tsx index 52c853d3..c4b673c7 100644 --- a/__tests__/usePreloadQuery-test.tsx +++ b/__tests__/usePreloadQuery-test.tsx @@ -749,5 +749,65 @@ describe('usePreloadQuery', () => { TestRenderer.act(() => jest.runAllImmediates()); expect(renderer.toJSON()).toEqual('Error Boundary'); }); + + it('issue-115', () => { + prefetched.next(environment, params, { id: '4' }); + + let data; + function Component(props) { + data = usePreloadedQuery(props.prefetched); + if (data.error) { + return 'Error Boundary'; + } + if (data.props && data.props.node) { + return data.props.node.name; + } + return data.props; + } + const renderer = TestRenderer.create( + + + , + ); + // Ensure that useEffect runs + TestRenderer.act(() => jest.runAllImmediates()); + expect(renderer.toJSON()).toEqual(null); + expect(data).toEqual(loadingData); + + dataSource.next(response); + dataSource.complete(); + TestRenderer.act(() => jest.runAllImmediates()); + expect(renderer.toJSON()).toEqual('Zuck'); + expect(data.props).toEqual({ + node: { + id: '4', + name: 'Zuck', + }, + }); + + TestRenderer.act(() => renderer.unmount()); + TestRenderer.act(() => jest.runAllImmediates()); + prefetched.next(environment, params, { id: '4' }); + dataSource.next(response); + dataSource.complete(); + TestRenderer.act(() => jest.runAllImmediates()); + expect((prefetched.getValue(environment) as any).props).toEqual({ + node: { + id: '4', + name: 'Zuck', + }, + }); + }); + + it('dispose subscription', () => { + const callback = jest.fn(() => {}); + const dispose = prefetched.subscribe(callback); + dispose(); + prefetched.next(environment, params, { id: '4' }); + dataSource.next(response); + dataSource.complete(); + TestRenderer.act(() => jest.runAllImmediates()); + expect(callback).not.toBeCalled(); + }); }); }); diff --git a/src/loadQuery.ts b/src/loadQuery.ts index 13d11e78..54c71311 100644 --- a/src/loadQuery.ts +++ b/src/loadQuery.ts @@ -8,11 +8,10 @@ const internalLoadQuery = promise = false, ): LoadQuery => { let data: RenderProps | null | Promise = null; - let listener; + let listener = undefined; + let queryFetcher = new QueryFetcher(true); - const queryFetcher = new QueryFetcher(true); - - const prev = { + let prev = { environment: null, gqlQuery: null, variables: null, @@ -22,7 +21,16 @@ const internalLoadQuery = const dispose = (): void => { queryFetcher.dispose(); - listener = null; + queryFetcher = new QueryFetcher(true); + listener = undefined; + data = null; + prev = { + environment: null, + gqlQuery: null, + variables: null, + options: null, + query: null, + }; }; const next = ( @@ -73,7 +81,9 @@ const internalLoadQuery = const subscribe = (callback: (value) => any): (() => void) => { listener = callback; - return dispose; + return (): void => { + listener = null; + }; }; return { next,