Skip to content

Instantly share code, notes, and snippets.

@ronaldruzicka
Last active February 9, 2021 08:57
Show Gist options
  • Save ronaldruzicka/452edce7727b767128e868c8b2d2e889 to your computer and use it in GitHub Desktop.
Save ronaldruzicka/452edce7727b767128e868c8b2d2e889 to your computer and use it in GitHub Desktop.
Example of separated React context for state and updater function for better performance in Typescript
import { createContext, useContext, useState } from 'react'
type User = {
firstName: string
lastName: string
email: string
}
type Updater = (user: User) => void
type UserProviderProps = {
children: React.ReactNode | React.ReactNode[]
}
const UserContext = createContext<User | Record<string, never>>({})
const UserUpdaterContext = createContext<Updater>(() => undefined)
const UserProvider = ({ children }: UserProviderProps) => {
const [state, setState] = useState<User | Record<string, never>>()
const setUserData = (user: User) => {
setState((prevUser) => {
if (prevUser !== null)) {
return { ...prevUser, ...userData };
}
return userData;
});
}
return (
<UserContext.Provider value={state}>
<UserUpdaterContext.Provider value={setUserData}>{children}</UserUpdaterContext.Provider>
</UserContext.Provider>
)
}
const useUserState = () => {
const context = useContext(UserContext)
if (typeof context === 'undefined') {
throw new Error('useUserState must be used within a UserProvider')
}
return context
}
const useUserUpdater = () => {
const context = useContext(UserUpdaterContext)
if (typeof context === 'undefined') {
throw new Error('useUserUpdater must be used within a UserProvider')
}
return context
}
export { UserProvider, useUserState, useUserUpdater }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment