DEV Community

Cover image for Stop Over-Rerenders: Smarter State Sharing in React with `useContextSelector`
sperez927
sperez927

Posted on

Stop Over-Rerenders: Smarter State Sharing in React with `useContextSelector`

🚫 Problem: Global Context = Silent Performance Killer

React's Context API is often misused as global state. It works - until updates to one part of the state cause every consumer to re-render.
We ran into this on a dashboard with many components reading shared filters. One toggle = full tree re-render. Not okay.

✅ Solution: Replace useContext with useContextSelector

Install the context-selector lib:

npm install use-context-selector

Then replace:

const { filters } = useContext(AppContext);

With:

const filters = useContextSelector(AppContext, ctx => ctx.filters)

Now only the components that care about filters will re-render.

🧪 Working Example

import { createContext, useContextSelector, useContext, } from 'use-context-selector'; import React, { useState } from 'react'; const AppContext = createContext(null); function Provider({ children }) { const [count, setCount] = useState(0); const [text, setText] = useState(""); const value = { count, setCount, text, setText }; return <AppContext.Provider value={value}>{children}</AppContext.Provider>; } function CountDisplay() { const count = useContextSelector(AppContext, ctx => ctx.count); console.log('Render: CountDisplay'); return <div>Count: {count}</div>; } function TextDisplay() { const text = useContextSelector(AppContext, ctx => ctx.text); console.log('Render: TextDisplay'); return <div>Text: {text}</div>; } 
Enter fullscreen mode Exit fullscreen mode

Toggling one field no longer rerenders both. Easy win, real speed boost.

🧠 Takeaway

  • Avoid useContext for frequently-updated state
  • useContextSelector = scoped updates + happy FPS

Top comments (0)