liveBook · Manning

Use-context-selector

As explained in React in Depth

useContextSelector is a hook that reads a selected portion of a React context value and limits updates to components whose selected value changes.

React context normally notifies every consumer when its value changes, even if a consumer needs only one property. use-context-selector lets a component select the part it reads, so an unrelated change need not re-render that component. It is an optimization for shared context state, not a replacement for choosing an appropriate state-management approach. section 2.1.3 section 8.9

The setup has two parts:

  • Create the context with createContext from use-context-selector; a context created with React’s createContext is not interchangeable here. section 2.1.3
  • Read it with useContextSelector(Context, selector), or put that call behind a domain hook that accepts the selector. Select the value a consumer actually needs. section 2.1.3 section 8.4.2

A dark-mode toggle

A provider exposes isDarkMode and a toggle callback. A button that needs the current mode selects isDarkMode; the toggle component selects only the callback. Defining that callback with useCallback and a functional state update keeps it stable across mode changes. The toggle component therefore need not re-render for the changed mode, although its child button still reads the mode to choose its styling. section 2.1.3

Listing 2.3 Dark mode with context selector
import { useState, useCallback, memo } from "react";
import {    #1
  createContext,    #1
  useContextSelector,    #1
} from "use-context-selector";    #1
const DarkModeContext = createContext({});
function Button({ children, ...rest }) {
  const isDarkMode =     #2
    useDarkMode((ctx) => ctx.isDarkMode);   #2
  ...
}
function ToggleButton() {
  const toggle = useDarkMode((ctx) => ctx.toggle);    #3
  return <Button onClick={toggle}>Toggle mode</Button>;
}
const Header = memo(function Header() {
  ...
});
function Main() {
  const isDarkMode =    #3
    useDarkMode((ctx) => ctx.isDarkMode);  #3
  ...
}
function DarkModeProvider({ children }) {
  const [isDarkMode, setDarkMode] = useState(false);
  const toggle =     #4
    useCallback(() => setDarkMode((v) => !v), []);  #4
  const contextValue = { isDarkMode, toggle };    #5
  return (
    <DarkModeContext.Provider value={contextValue}>
      {children}
    </DarkModeContext.Provider>
  );
}
function useDarkMode(selector) {     #6
  return useContextSelector(   #6
  DarkModeContext, #6
  selector  #6
);  #6
}
export default function App() {
  return (
    <DarkModeProvider>
      <Main />
    </DarkModeProvider>
  );
}

The dark-mode implementation places the package’s createContext and useContextSelector alongside separate selectors for state and the stable toggle action. section 2.1.3

The same pattern scales to a reducer-backed provider: a small useData(selector) hook can expose selected state or actions, while feature hooks retrieve the values they need. It can sit alongside useReducer, useReduction, and Immer; it addresses context-consumer rendering rather than reducer boilerplate or immutable updates. section 8.4 section 8.4.2

Tests still need a provider. When rendering a context-dependent component alone, wrap it in the package-created context’s Provider with the selected value or a mock callback; then assert the rendered result or interaction. React’s built-in context follows the same testing pattern, without selectors. section 10.3.3

How React in Depth covers it

How deep it goes
Shows context creation, selector hooks, stable callbacks, feature hooks, and provider-backed tests; does not examine the library’s internals.
Examples
Uses a dark-mode toggle, a reducer-backed goal tracker, and isolated button tests with mock context values.
What it assumes
Assumes familiarity with React context, hooks, providers, and component tests rather than teaching those foundations from zero.
What you can do after
Apply it via use-context-selector to build selective context hooks and test their consumers with a provider.
How it connects
Connects React context, custom hooks, useCallback, reducers, Immer, and component testing.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of React in Depth. The section links point to the parts of the book it draws on.