Hi friends. In my last projects I use providers a lot:
- Auth (login, logout, user)
- AppState (which part of the app is loaded and which is not, user settings)
- NavigationProvider (page neighbors, go next, go back)
- ModalsProvider (open in modal form a component with some props)
So I came up with a provider snippet, which is easy to copy, past, expand and use from everywhere.
Boilerplate
Provider.tsx
import React, { createContext, useState } from 'react'
// rename Context and Provider to something meaningful, they will be imported from other components
interface Props {
children: JSX.Element | JSX.Element[]
}
interface State {}
interface Methods {}
interface ContextType {
state: State
methods: Methods
}
const defaultContextValue = {} as ContextType
export const Context = createContext<ContextType>(defaultContextValue)
const defaultState = {}
const Provider: React.FC<Props> = ({ children }) => {
const [state, setState] = useState<State>(defaultState)
// here write some functions that change state, then put them to the mothods object
const methods = {}
const contextValue = { state, methods }
return <Context.Provider value={contextValue}>{children}</Context.Provider>
}
export default Provider
Usage example
Provider
App.tsx
import Provider1 from './Provider1'
import Provider2 from './Provider2'
const App = () => {
return (
<Provider1>
<Provider2>
</Provider2>
</Provider1>
)
}
Context
When every provider has the same structure, you can use any of them easily/intuitively from anywhere.
Component.ts
import { useContext } from 'react'
import { Context1 } from './Provider1'
import { Context2 } from './Provider2'
const Component = () => {
const { state: provider1State, methods: provider1Methods } =
useContext(Context1)
const { state: provider2State, methods: provider2Methods } =
useContext(Context2)
return (
<div className='someComponent'>
<div>{provider1State.someField}</div>
<div>{provider2State.someField}</div>
<button>provider1Methods.someMethod</button>
<button>provider2Methods.someMethod</button>
</div>
)
}
In a real project you'll have meaningful names for every provider (not Provider1, Provider2 as in the example above) so it'll be easy to read and write code even when many providers meats together in one component. E.g. authState.userName
, authMethods.login
, appState.contentLoaded
.
If you don't like such an approach, look at useReducer hook.
Top comments (0)