Context API is a way to pass data through the component tree without having to manually pass props down at every level.
props
from top level each level down to the level where it is consumed.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
Context is created using the createContext
function.
This function returns a context
object.
import { createContext } from "react"; export const ThemeContext = createContext({ theme: "dark", setTheme: (theme: string) => {}, });
Provider
The Provider
accepts a value
prop, which determines what data will be shared across the component tree.
All descendant components that consume the context
will have access to this value
.
The order of the context Provider does not matter.
When you need value from any part of the Context hierarchy in consumption, you would just call the useContext
.
import { createContext } from "react"; export const ThemeContext = createContext({ theme: "dark", setTheme: (theme: string) => {}, }); function App() { const [theme, setTheme] = useState('light'); // ... return ( <ThemeContext.Provider value={theme}> <Page /> </ThemeContext.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.
If you don't wrap your components with Context.Provider
they won't get re-rendered when a value in createContext
changes
// 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); // ... }
import React, { createContext, useState, useContext } from 'react'; // Create Context const MyContext = createContext(); // App component const App = () => { const [user, setUser] = useState({ name: 'Alice' }); return ( <MyContext.Provider value={user}> <ChildComponent /> </MyContext.Provider> ); }; // Child component that consumes the context const ChildComponent = () => { const user = useContext(MyContext); // Accessing context value return <div>Hello, {user.name}!</div>; }; export default App;