Last active
July 22, 2020 13:10
-
-
Save donaldpipowitch/7310d7b9e4b6d467134c425e8732adc6 to your computer and use it in GitHub Desktop.
useSessionStorage and useLocalStorage for easy mocking - similar to MemoryRouter in react-router, but for storage
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { FC, useMemo } from 'react'; | |
import { | |
LocalStorageProvider, | |
SessionStorageProvider, | |
} from './use-storage'; | |
// this is just a dumb mock of the storage interface | |
class MemoryStorage implements Storage { | |
private data: Record<string, string> = {}; | |
getItem(key: string) { | |
return this.data[key] ?? null; | |
} | |
setItem(key: string, value: string) { | |
this.data[key] = value; | |
} | |
removeItem(key: string) { | |
delete this.data[key]; | |
} | |
clear() { | |
this.data = {}; | |
} | |
get length() { | |
return Object.keys(this.data).length; | |
} | |
key(index: number) { | |
return Object.keys(this.data)[index] ?? null; | |
} | |
} | |
type Data = { [key: string]: unknown }; | |
function useStorageMock(initialData: Data) { | |
return useMemo(() => { | |
const storage = new MemoryStorage(); | |
Object.keys(initialData).forEach((key) => { | |
const value = initialData[key]; | |
if (typeof value === 'string') { | |
storage.setItem(key, value); | |
} else { | |
storage.setItem(key, JSON.stringify(value)); | |
} | |
}); | |
return storage; | |
// eslint-disable-next-line react-hooks/exhaustive-deps | |
}, []); | |
} | |
type Props = { initialData: Data }; | |
export const MockedLocalStorage: FC<Props> = ({ children, initialData }) => { | |
const storage = useStorageMock(initialData); | |
return ( | |
<LocalStorageProvider value={storage}>{children}</LocalStorageProvider> | |
); | |
}; | |
export const MockedSessionStorage: FC<Props> = ({ children, initialData }) => { | |
const storage = useStorageMock(initialData); | |
return ( | |
<SessionStorageProvider value={storage}>{children}</SessionStorageProvider> | |
); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createContext, useContext } from 'react'; | |
const LocalStorageContext = createContext(localStorage); | |
export function useLocalStorage() { | |
return useContext(LocalStorageContext); | |
} | |
export const LocalStorageProvider = LocalStorageContext.Provider; | |
const SessionStorageContext = createContext(sessionStorage); | |
export function useSessionStorage() { | |
return useContext(SessionStorageContext); | |
} | |
export const SessionStorageProvider = SessionStorageContext.Provider; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment