Suggest an editImprove this articleRefine the answer for “What does the "selector pattern" do in context?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)The **selector pattern** is an approach where a component subscribes **only to part of the context**, not the whole `value` object, so it re-renders only when the specific field it reads actually changes. **Key point:** libraries like `use-context-selector` compare the old and new selected value with `Object.is` and re-render the component only if it actually changed.Shown above the full answer for quick recall.Answer (EN)Image## The problem it solves A regular context works like this: ```javascript const AppContext = createContext({ user, theme, cart }); const value = { user, theme, cart }; // the object changes by reference <AppContext.Provider value={value}> <Child /> </AppContext.Provider> ``` If inside `Child` you read **only** `theme`: ```javascript const { theme } = useContext(AppContext); ``` then when `user` or `cart` changes, `theme` stays the same, **but the component still re-renders**, because `value` changed **by reference**. This is a fundamental behavior of React Context. Even if only one part changed, all consumers re-render. --- ## Selector pattern: how it solves this **The idea:** a component subscribes **only to part of the context**, not the whole `value` object. In other words: > "Watch only `theme`, and do not react to changes in `user` or `cart`." --- ## Example with the `use-context-selector` library This library implements the selector pattern for the Context API. ### 1. Create the context ```javascript import { createContext } from "use-context-selector"; export const AppContext = createContext({ user: { name: "Tim" }, theme: "light", cart: [], }); ``` ### 2. Wrap the Provider ```javascript import { AppContext } from "./AppContext"; export function AppProvider({ children }) { const [user, setUser] = useState({ name: "Tim" }); const [theme, setTheme] = useState("light"); const [cart, setCart] = useState([]); const value = { user, theme, cart, setUser, setTheme, setCart }; return <AppContext.Provider value={value}>{children}</AppContext.Provider>; } ``` ### 3. Use selectors in consumers ```javascript import { useContextSelector } from "use-context-selector"; import { AppContext } from "./AppContext"; function ThemeSwitcher() { const theme = useContextSelector(AppContext, ctx => ctx.theme); const setTheme = useContextSelector(AppContext, ctx => ctx.setTheme); console.log("ThemeSwitcher render"); return ( <button onClick={() => setTheme(theme === "light" ? "dark" : "light")}> {theme} </button> ); } function UserName() { const user = useContextSelector(AppContext, ctx => ctx.user); console.log("UserName render"); return <p>Hello, {user.name}</p>; } ``` Now: - When `theme` changes, only `ThemeSwitcher` re-renders; - When `user` changes, only `UserName` does; - Other consumers are left untouched. --- ## Why this works - Each consumer subscribes **to a specific sub-value** from the context. - Under the hood, `use-context-selector` creates a "mini-subscription" to only the selected fragment of `value`. - When the context updates, React compares the **old and new selected value** with `Object.is`, and if they are equal, the component does not re-render. --- ## Without third-party libraries (a basic implementation) You can implement the selector approach manually by **splitting the contexts**: ```javascript export const UserContext = createContext(); export const ThemeContext = createContext(); export const CartContext = createContext(); ``` and consuming exactly the one you need. This is the simplest equivalent of the "selector pattern", just not at the value level, but at the level of "context as an entity". --- ## Summary | Approach | Behavior | |---|---| | `useContext` | The component is subscribed to **the whole value**, it re-renders on any change | | `use-context-selector` | The component is subscribed **to the selected field**, it re-renders only when that changes | | "Many contexts" | Each has its own area of responsibility, also a variant of the selector pattern | --- ### The selector pattern helps: reduce re-renders on frequent context updates improve the performance of large component trees write flexible, reactive contexts without heavy stores (Redux, Zustand)For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.