From b255fd57820bad20e65147a635be461af376b0ba Mon Sep 17 00:00:00 2001 From: Michael A Tomcal Date: Fri, 28 Aug 2020 17:18:19 -0700 Subject: [PATCH] fix(queryHelpers): fix ssr logic --- __tests__/queryHelpers.spec.js | 30 ++++++++++++++++++++++-------- src/queryHelpers.js | 14 ++++++++------ src/useFetchye.js | 12 +++++------- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/__tests__/queryHelpers.spec.js b/__tests__/queryHelpers.spec.js index 0051669..fb7bfbc 100644 --- a/__tests__/queryHelpers.spec.js +++ b/__tests__/queryHelpers.spec.js @@ -20,34 +20,48 @@ import { describe('isLoading', () => { it('should return true if loading cache true', () => { - expect(isLoading(true, {}, {})).toBeTruthy(); + expect(isLoading({ + loading: true, data: undefined, numOfRenders: 2, options: {}, + })).toBeTruthy(); }); it('should return true if first render is true', () => { - expect(isLoading(false, { current: true }, {})).toBeTruthy(); + expect(isLoading({ + loading: false, data: undefined, numOfRenders: 1, options: { }, + })).toBeTruthy(); }); it('should return false if first render is true and lazy is true', () => { - expect(isLoading(false, { current: true }, { lazy: true })).toBeFalsy(); + expect(isLoading({ + loading: false, data: undefined, numOfRenders: 1, options: { lazy: true }, + })).toBeFalsy(); }); it('should return false if all args are false', () => { - expect(isLoading(false, { current: false }, { lazy: false })).toBeFalsy(); + expect(isLoading({ loading: false, numOfRenders: 2, options: { lazy: false } })).toBeFalsy(); }); }); describe('getData', () => { it('should return data if data exists', () => { - expect(getData({})).toBeTruthy(); + expect(getData({ fakeData: true }, 0)).toEqual({ fakeData: true }); }); it('should return initialData data', () => { - expect(getData(undefined, { initialData: { data: { fakeData: true } } })).toBeTruthy(); + expect(getData(undefined, 1, { initialData: { data: { fakeData: true } } })) + .toEqual({ fakeData: true }); + }); + it('should return not initialData data on >1 renders', () => { + expect(getData(undefined, 2, { initialData: { data: { fakeData: true } } })).toBeUndefined(); }); }); describe('getError', () => { + const error = new Error('fake error'); it('should return error if error exists', () => { - expect(getError(new Error('fake error'))).toBeTruthy(); + expect(getError(error, 0)).toEqual(error); }); it('should return initialData error', () => { - expect(getError(undefined, { initialData: { error: new Error('fake error') } })).toBeTruthy(); + expect(getError(undefined, 1, { initialData: { error } })).toEqual(error); + }); + it('should return not initialData error on >1 renders', () => { + expect(getError(undefined, 2, { initialData: { error } })).toBeUndefined(); }); }); diff --git a/src/queryHelpers.js b/src/queryHelpers.js index f14e6c9..b145de6 100644 --- a/src/queryHelpers.js +++ b/src/queryHelpers.js @@ -14,11 +14,13 @@ * permissions and limitations under the License. */ -export const isLoading = (loading, isFirstRender, options) => { +export const isLoading = ({ + loading, data, numOfRenders, options, +}) => { if (loading) { return true; } - if (isFirstRender?.current) { + if (!data && numOfRenders === 1) { if (options.lazy) { return false; } @@ -27,15 +29,15 @@ export const isLoading = (loading, isFirstRender, options) => { return false; }; -export const getData = (data, options) => { - if (!data) { +export const getData = (data, numOfRenders, options) => { + if (!data && numOfRenders === 1) { return options?.initialData?.data; } return data; }; -export const getError = (error, options) => { - if (!error) { +export const getError = (error, numOfRenders, options) => { + if (!error && numOfRenders === 1) { return options?.initialData?.error; } return error; diff --git a/src/useFetchye.js b/src/useFetchye.js index a028bd4..275395f 100644 --- a/src/useFetchye.js +++ b/src/useFetchye.js @@ -35,14 +35,12 @@ export const useFetchye = ( const selectedFetcher = typeof fetcher === 'function' ? fetcher : defaultFetcher; const computedKey = computeKey(key, defaultMapOptionsToKey(mapOptionsToKey(options))); const { data, loading, error } = useFetchyeSelector(computedKey.hash); - const isFirstRender = useRef(!data && !options?.initialData?.data); + const numOfRenders = useRef(0); + numOfRenders.current += 1; useEffect(() => { if (options.lazy || !computedKey) { return; } - if (isFirstRender.current !== false) { - isFirstRender.current = false; - } if (!data && !error && !loading) { (async () => { await runAsync({ @@ -52,9 +50,9 @@ export const useFetchye = ( } }, [data, loading, error, computedKey, selectedFetcher, options, dispatch, fetchClient]); return { - isLoading: isLoading(loading, options), - error: getError(error, options), - data: getData(data, options), + isLoading: isLoading({ loading, numOfRenders: numOfRenders.current, options }), + error: getError(error, numOfRenders.current, options), + data: getData(data, numOfRenders.current, options), run() { return runAsync({ dispatch, computedKey, fetcher: selectedFetcher, fetchClient, options,