Last active
February 9, 2021 08:57
-
-
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
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, 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