From efab88fd0f676f43996435d20593441126e3b520 Mon Sep 17 00:00:00 2001 From: Emmanuel Chambon Date: Thu, 27 May 2021 10:55:23 +0200 Subject: [PATCH] feat(use-dataloader): add cache key prefix on Provider --- .../use-dataloader/src/DataLoaderProvider.js | 34 ++++++++----- .../src/__tests__/DataLoaderProvider.test.js | 49 +++++++++++++++++++ 2 files changed, 72 insertions(+), 11 deletions(-) diff --git a/packages/use-dataloader/src/DataLoaderProvider.js b/packages/use-dataloader/src/DataLoaderProvider.js index 1ed650d5e..50f5e2873 100644 --- a/packages/use-dataloader/src/DataLoaderProvider.js +++ b/packages/use-dataloader/src/DataLoaderProvider.js @@ -9,7 +9,7 @@ import React, { export const DataLoaderContext = createContext() -const DataLoaderProvider = ({ children }) => { +const DataLoaderProvider = ({ children, cacheKeyPrefix }) => { const cachedData = useRef({}) const reloads = useRef({}) @@ -34,11 +34,11 @@ const DataLoaderProvider = ({ children }) => { if (key && typeof key === 'string' && newData) { setCachedData(actualCachedData => ({ ...actualCachedData, - [key]: newData, + [`${cacheKeyPrefix ? `${cacheKeyPrefix}-` : ''}${key}`]: newData, })) } }, - [setCachedData], + [setCachedData, cacheKeyPrefix], ) const addReload = useCallback( @@ -76,13 +76,13 @@ const DataLoaderProvider = ({ children }) => { if (key && typeof key === 'string') { setCachedData(actualCachedData => { const tmp = actualCachedData - delete tmp[key] + delete tmp[`${cacheKeyPrefix ? `${cacheKeyPrefix}-` : ''}${key}`] return tmp }) } }, - [setCachedData], + [setCachedData, cacheKeyPrefix], ) const clearAllCachedData = useCallback(() => { setCachedData({}) @@ -100,13 +100,20 @@ const DataLoaderProvider = ({ children }) => { ) }, []) - const getCachedData = useCallback(key => { - if (key) { - return cachedData.current[key] || undefined - } + const getCachedData = useCallback( + key => { + if (key) { + return ( + cachedData.current[ + `${cacheKeyPrefix ? `${cacheKeyPrefix}-` : ''}${key}` + ] || undefined + ) + } - return cachedData.current - }, []) + return cachedData.current + }, + [cacheKeyPrefix], + ) const getReloads = useCallback(key => { if (key) { @@ -151,9 +158,14 @@ const DataLoaderProvider = ({ children }) => { } DataLoaderProvider.propTypes = { + cacheKeyPrefix: PropTypes.string, children: PropTypes.node.isRequired, } +DataLoaderProvider.defaultProps = { + cacheKeyPrefix: undefined, +} + export const useDataLoaderContext = () => useContext(DataLoaderContext) export default DataLoaderProvider diff --git a/packages/use-dataloader/src/__tests__/DataLoaderProvider.test.js b/packages/use-dataloader/src/__tests__/DataLoaderProvider.test.js index 337f34b20..b04cb05ed 100644 --- a/packages/use-dataloader/src/__tests__/DataLoaderProvider.test.js +++ b/packages/use-dataloader/src/__tests__/DataLoaderProvider.test.js @@ -6,6 +6,11 @@ import DataLoaderProvider, { useDataLoaderContext } from '../DataLoaderProvider' const wrapper = ({ children }) => ( {children} ) + +const wrapperWithCacheKey = ({ children }) => ( + {children} +) + describe('DataLoaderProvider', () => { test('should render correctly', async () => { render(Test) @@ -23,6 +28,22 @@ describe('DataLoaderProvider', () => { expect(Object.values(result.current.getCachedData()).length).toBe(1) expect(result.current.getCachedData().test).toBe('test') }) + + test('should add cached data with cacheKeyPrefix', async () => { + const { result } = renderHook(useDataLoaderContext, { + wrapper: wrapperWithCacheKey, + }) + expect(result.current.getCachedData()).toStrictEqual({}) + + act(() => { + result.current.addCachedData('test', 'test') + result.current.addCachedData(3, 'testWrong') + }) + + expect(Object.values(result.current.getCachedData()).length).toBe(1) + expect(result.current.getCachedData()['sample-test']).toBe('test') + }) + test('should delete cached data', async () => { const { result } = renderHook(useDataLoaderContext, { wrapper }) @@ -49,6 +70,34 @@ describe('DataLoaderProvider', () => { expect(result.current.getCachedData()).toStrictEqual({}) }) + test('should delete cached data with cacheKeyPrefix', async () => { + const { result } = renderHook(useDataLoaderContext, { + wrapper: wrapperWithCacheKey, + }) + + act(() => { + result.current.addCachedData('testA', 'testA') + result.current.addCachedData('testB', 'testB') + result.current.addCachedData('testC', 'testC') + result.current.addCachedData('testD', 'testD') + result.current.addCachedData('testE', 'testE') + }) + expect(result.current.getCachedData('testA')).toBe('testA') + + act(() => { + result.current.clearCachedData() + result.current.clearCachedData('testA') + }) + expect(Object.values(result.current.getCachedData()).length).toBe(4) + expect(result.current.getCachedData().testA).toBe(undefined) + + act(() => { + result.current.clearAllCachedData() + }) + expect(Object.values(result.current.getCachedData()).length).toBe(0) + expect(result.current.getCachedData()).toStrictEqual({}) + }) + test('should get cached data', async () => { const { result } = renderHook(useDataLoaderContext, { wrapper }) expect(result.current.getCachedData()).toStrictEqual({})