Skip to content

[Suggestion]: #7973

Description

@keshavjha005

Summary

Optimizing Context Consumption with Selectors

Problem

React’s Context API re-renders all consumers when any value in the context changes, even if the consumer only needs a small part. In large apps, this can affect performance.

Solution: Context Selector Pattern

A custom hook useContextSelector lets you select only the value you need.

importReact,{createContext,useContext,useRef,useSyncExternalStore}from"react";// Create contextconstAppContext=createContext();// Provider exampleexportfunctionAppProvider({ children }){const[user,setUser]=React.useState({name: "Jane",age: 25});const[theme,setTheme]=React.useState("light");conststore=useRef({ user, theme, setUser, setTheme });store.current={ user, theme, setUser, setTheme };return(<AppContext.Providervalue={store}>{children}</AppContext.Provider>);}// useContextSelector hookexportfunctionuseContextSelector(selector){conststore=useContext(AppContext);constgetSnapshot=()=>selector(store.current);// This only re-renders when the selected value changesreturnuseSyncExternalStore((cb)=>{// naive implementation; use event emitter for productionreturn()=>{};},getSnapshot,getSnapshot);}// Usage examplefunctionUserName(){// Only re-renders when user.name changesconstname=useContextSelector(ctx=>ctx.user.name);return<div>User: {name}</div>;}functionThemeDisplay(){// Only re-renders when theme changesconsttheme=useContextSelector(ctx=>ctx.theme);return<div>Theme: {theme}</div>;}

Benefits

  • Prevents unnecessary re-renders
  • Improves performance in large apps
  • Easy to use with existing Context API

References

Page

No response

Details

Optimizing Context Consumption with Selectors

Problem

React’s Context API re-renders all consumers when any value in the context changes, even if the consumer only needs a small part. In large apps, this can affect performance.

Solution: Context Selector Pattern

A custom hook useContextSelector lets you select only the value you need.

importReact,{createContext,useContext,useRef,useSyncExternalStore}from"react";// Create contextconstAppContext=createContext();// Provider exampleexportfunctionAppProvider({ children }){const[user,setUser]=React.useState({name: "Jane",age: 25});const[theme,setTheme]=React.useState("light");conststore=useRef({ user, theme, setUser, setTheme });store.current={ user, theme, setUser, setTheme };return(<AppContext.Providervalue={store}>{children}</AppContext.Provider>);}// useContextSelector hookexportfunctionuseContextSelector(selector){conststore=useContext(AppContext);constgetSnapshot=()=>selector(store.current);// This only re-renders when the selected value changesreturnuseSyncExternalStore((cb)=>{// naive implementation; use event emitter for productionreturn()=>{};},getSnapshot,getSnapshot);}// Usage examplefunctionUserName(){// Only re-renders when user.name changesconstname=useContextSelector(ctx=>ctx.user.name);return<div>User: {name}</div>;}functionThemeDisplay(){// Only re-renders when theme changesconsttheme=useContextSelector(ctx=>ctx.theme);return<div>Theme: {theme}</div>;}

Benefits

  • Prevents unnecessary re-renders
  • Improves performance in large apps
  • Easy to use with existing Context API

References

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions