Created
October 27, 2023 14:09
-
-
Save jlozovei/50e6db3a207f6d71cbab56481701707e to your computer and use it in GitHub Desktop.
React + RTL context injection
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
// context/index.js | |
import { useReducer, useEffect, useMemo, createContext } from 'react'; | |
import { reducer1, reducer2, reducer3 } from './reducers'; | |
const Context = createContext({}); | |
const STORAGE_KEY = 'my_awesome_storage' | |
const defaultState = { | |
user: { | |
name: null, | |
email: null | |
} | |
} | |
const combineReducers = | |
(...reducers) => | |
(state, action) => { | |
for (let i = 0; i < reducers.length; i++) state = reducers[i](state, action); | |
return state; | |
}; | |
const Provider = ({ injectedState = null, children }) => { | |
const [state, dispatch] = useReducer( | |
combineReducers(reducer1, reducer2, reducer3), | |
injectedState || defaultState | |
); | |
const contextValue = useMemo(() => { | |
return { state, dispatch }; | |
}, [state, dispatch]); | |
useEffect(() => { | |
const stored = JSON.parse(localStorage.getItem(STORAGE_KEY)); | |
if (stored) { | |
dispatch({ | |
type: 'RETRIEVE_STORED_STATE', | |
payload: stored | |
}); | |
} | |
}, []); | |
useEffect(() => { | |
if (state !== defaultState) { | |
localStorage.setItem(STORAGE_KEY, JSON.stringify(state)); | |
} | |
}, [state]); | |
return <Context.Provider value={contextValue}>{children}</Context.Provider>; | |
}; | |
export { Context, Provider }; |
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
// utils/customTestRender.js | |
import { Provider as ContextProvider, ToastProvider } from '@/context'; | |
function Wrapper({ children, ...options }) { | |
return ( | |
<ContextProvider injectedState={{ ...options?.context }}> | |
{children} | |
</ContextProvider> | |
); | |
} | |
const renderWithProviders = (ui, options = { wrapperProps: {} }) => | |
render(ui, { wrapper: (props) => <Wrapper {...props} {...options?.wrapperProps} />, ...options }); | |
export { renderWithProviders }; |
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
// some test file | |
import { screen } from '@testing-library/react'; | |
import { SomeComponent } from '@/components'; | |
import { renderWithProviders } from '@/utils/customTestRender'; | |
describe('some test', () => { | |
it('Should test something', async () => { | |
const context = { | |
user: { | |
name: 'John Doe', | |
email: 'john@doe.com' | |
} | |
}; | |
renderWithProviders(<SomeComponent />, { wrapperProps: { context } }); | |
// your average expects here... | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment