- Spec files
npm-react
Describes: pkg:npm/react@19.1.x
- Description
- React is a JavaScript library for building user interfaces with a declarative, component-based approach.
- Author
- tessl
- Last updated
context.md docs/
1# Context API23React Context for sharing values between components without explicit prop passing. Context provides a way to pass data through the component tree without having to pass props down manually at every level.45## Capabilities67### createContext89Creates a React context object for sharing values across the component tree.1011```typescript { .api }12/**13* Creates a new Context object14* @param defaultValue - Default value used when component has no matching Provider above it15* @returns Context object with Provider and Consumer components16*/17function createContext<T>(defaultValue: T): React.Context<T>;1819interface Context<T> {20Provider: React.Provider<T>;21Consumer: React.Consumer<T>;22displayName?: string;23}24```2526**Usage Examples:**2728```typescript29import React, { createContext, useContext, useState } from "react";3031// Create theme context with default value32interface ThemeContextType {33theme: "light" | "dark";34toggleTheme: () => void;35}3637const ThemeContext = createContext<ThemeContextType>({38theme: "light",39toggleTheme: () => {}40});4142// Provider component43function ThemeProvider({ children }: { children: React.ReactNode }) {44const [theme, setTheme] = useState<"light" | "dark">("light");4546const toggleTheme = () => {47setTheme(prev => prev === "light" ? "dark" : "light");48};4950return (51<ThemeContext.Provider value={{ theme, toggleTheme }}>52{children}53</ThemeContext.Provider>54);55}5657// Consumer using useContext hook58function ThemedButton() {59const { theme, toggleTheme } = useContext(ThemeContext);6061return (62<button63onClick={toggleTheme}64style={{65backgroundColor: theme === "light" ? "white" : "black",66color: theme === "light" ? "black" : "white"67}}68>69Toggle theme (current: {theme})70</button>71);72}73```7475### Provider Component7677Component that provides context values to its descendants.7879```typescript { .api }80/**81* Provides context value to descendant components82*/83interface Provider<T> {84/**85* Value to provide to consumers86*/87value: T;88/**89* Child components that can consume the context90*/91children?: React.ReactNode;92}93```9495**Usage Examples:**9697```typescript98import React, { createContext, useState } from "react";99100interface User {101id: string;102name: string;103email: string;104}105106interface UserContextType {107user: User | null;108login: (user: User) => void;109logout: () => void;110}111112const UserContext = createContext<UserContextType>({113user: null,114login: () => {},115logout: () => {}116});117118function UserProvider({ children }: { children: React.ReactNode }) {119const [user, setUser] = useState<User | null>(null);120121const login = (userData: User) => {122setUser(userData);123};124125const logout = () => {126setUser(null);127};128129return (130<UserContext.Provider value={{ user, login, logout }}>131{children}132</UserContext.Provider>133);134}135136function App() {137return (138<UserProvider>139<Header />140<Main />141<Footer />142</UserProvider>143);144}145```146147### Consumer Component148149Legacy component for consuming context values (mostly replaced by useContext hook).150151```typescript { .api }152/**153* Consumes context value using render prop pattern154*/155interface Consumer<T> {156children: (value: T) => React.ReactNode;157}158```159160**Usage Examples:**161162```typescript163import React, { createContext } from "react";164165const ThemeContext = createContext("light");166167function ThemedButton() {168return (169<ThemeContext.Consumer>170{theme => (171<button className={`button-${theme}`}>172Themed Button ({theme})173</button>174)}175</ThemeContext.Consumer>176);177}178179// Preferred modern approach with useContext hook180function ModernThemedButton() {181const theme = useContext(ThemeContext);182183return (184<button className={`button-${theme}`}>185Themed Button ({theme})186</button>187);188}189```190191### useContext Hook192193Hook for consuming context values (covered in detail in Hooks documentation).194195```typescript { .api }196/**197* Consumes context value from the nearest Provider above198* @param context - React context object199* @returns Current context value200*/201function useContext<T>(context: React.Context<T>): T;202```203204## Advanced Patterns205206### Multiple Contexts207208```typescript209import React, { createContext, useContext } from "react";210211// User context212const UserContext = createContext<{ name: string } | null>(null);213214// Settings context215const SettingsContext = createContext<{ language: string }>({216language: "en"217});218219function UserProfile() {220const user = useContext(UserContext);221const settings = useContext(SettingsContext);222223if (!user) {224return <div>Please log in</div>;225}226227return (228<div>229<h1>Welcome, {user.name}!</h1>230<p>Language: {settings.language}</p>231</div>232);233}234235function App() {236return (237<UserContext.Provider value={{ name: "Alice" }}>238<SettingsContext.Provider value={{ language: "es" }}>239<UserProfile />240</SettingsContext.Provider>241</UserContext.Provider>242);243}244```245246### Context with Reducer247248```typescript249import React, { createContext, useContext, useReducer } from "react";250251interface State {252count: number;253user: { name: string } | null;254}255256type Action =257| { type: "increment" }258| { type: "decrement" }259| { type: "setUser"; user: { name: string } }260| { type: "logout" };261262function appReducer(state: State, action: Action): State {263switch (action.type) {264case "increment":265return { ...state, count: state.count + 1 };266case "decrement":267return { ...state, count: state.count - 1 };268case "setUser":269return { ...state, user: action.user };270case "logout":271return { ...state, user: null };272default:273return state;274}275}276277interface AppContextType {278state: State;279dispatch: React.Dispatch<Action>;280}281282const AppContext = createContext<AppContextType | null>(null);283284function AppProvider({ children }: { children: React.ReactNode }) {285const [state, dispatch] = useReducer(appReducer, {286count: 0,287user: null288});289290return (291<AppContext.Provider value={{ state, dispatch }}>292{children}293</AppContext.Provider>294);295}296297function useAppContext() {298const context = useContext(AppContext);299if (!context) {300throw new Error("useAppContext must be used within AppProvider");301}302return context;303}304305function Counter() {306const { state, dispatch } = useAppContext();307308return (309<div>310<p>Count: {state.count}</p>311<button onClick={() => dispatch({ type: "increment" })}>+</button>312<button onClick={() => dispatch({ type: "decrement" })}>-</button>313</div>314);315}316```317318### Avoiding Context Performance Issues319320```typescript321import React, { createContext, useContext, useMemo, useState } from "react";322323// Separate contexts for values and actions to prevent unnecessary re-renders324const StateContext = createContext<{ count: number; user: string | null }>(null!);325const ActionsContext = createContext<{326increment: () => void;327setUser: (user: string) => void;328}>(null!);329330function AppProvider({ children }: { children: React.ReactNode }) {331const [count, setCount] = useState(0);332const [user, setUser] = useState<string | null>(null);333334// Memoize actions to prevent re-creation on every render335const actions = useMemo(() => ({336increment: () => setCount(c => c + 1),337setUser: (newUser: string) => setUser(newUser)338}), []);339340// Memoize state to prevent unnecessary re-renders341const state = useMemo(() => ({ count, user }), [count, user]);342343return (344<StateContext.Provider value={state}>345<ActionsContext.Provider value={actions}>346{children}347</ActionsContext.Provider>348</StateContext.Provider>349);350}351352function useAppState() {353return useContext(StateContext);354}355356function useAppActions() {357return useContext(ActionsContext);358}359```360361## Types362363### Context-Related Types364365```typescript { .api }366interface Context<T> {367Provider: Provider<T>;368Consumer: Consumer<T>;369displayName?: string;370}371372interface Provider<T> {373value: T;374children?: ReactNode;375}376377interface Consumer<T> {378children: (value: T) => ReactNode;379}380381type ContextType<C extends Context<any>> = C extends Context<infer T> ? T : never;382```