Props
that don't need drilling
Context
is typically an object that holds the values that get consumed throughout the app
// context creation import { createContext } from 'react'; const ContextName = createContext( {...} ); // context consumption const { user } = useContext(ContextName);
createContext
createContext
returns a context
object
import { createContext } from "react"; export const ThemeContext = createContext({ theme: "dark", setTheme: (theme: string) => {}, });
Provider
If a component is not wrapped in the
Context.Provider
it will receive the default value that was set when the context was created. Provider's job is to override the default values, essentially providing dependency injection mechanism to React component tree
All consumers that are descendants of a Provider will re-render whenever the Provider’s value prop changes
Context.Provider
they won't get re-rendered when a value in createContext
changes
function App() { const [theme, setTheme] = useState('light'); // ... return ( <ThemeContext.Provider value={theme}> <Page /> </ThemeContext.Provider> ); }
// create Context import { createContext } from "react"; type ContextType = { theme: string; setTheme: (theme: string) => void; }; export const ThemeContext = createContext<ContextType | undefined>(undefined); // state and provider component (level above) import { PropsWithChildren, useState } from "react"; export const ThemeProvider = ({ children }: PropsWithChildren<{}>) => { const [theme, setTheme] = useState(); return ( <ThemeContext.Provider value={{ theme, setTheme }}> {children} </ThemeContext.Provider> ); }; // context consumption (level below) import { useContext } from 'react'; function MyComponent() { const theme = useContext(ThemeContext); // ... }