React context and app state
when app gets too big and you are passing state (prop drilling) 5 leves deep, you use app state.
use React Context or the Redux lib for this.
Context lets a parent component provide data to the entire tree below it.
Context works similar to CSS property inheritance, no matter how deep, an element will inherit that property unless some other DOM node in the middle overrides it.
example:

- redux is a library that helps manage state. seems to be less useful nowdays bc of the release of the React Context API.
if you need to change or update state in many different parts of your app, there are many Redux competitors that don't require learning new concepts. consider zutand, jotai, recoil.
Also React Context have some shortcomings that these libs aim to solve: 'convoluted' code and there is no easy way to modify the state passed down in context to child components. In React the only way to override some context coming from above is to wrap children into a context provider with a different value.
https://react.dev/learn/passing-data-deeply-with-context#use-cases-for-context
- I could use context to pass the currently logged in user.
- Routing
steps to implement context
- Create and export it with
export const MyContext = createContext(defaultValue) - Pass it to the
useContext(MyContext)Hook to read it in any child component, no matter how deep. - Wrap children into
<MyContext.Provider value={...}>to provide it from a parent.
//Section.js
import { LevelContext } from './LevelContext.js';
export default function Section({ level, children }) {
return (
<section className="section">
<LevelContext.Provider value={level}>
{children}
</LevelContext.Provider>
</section>
);
}
Context vs useQuery everywhere
Some querying libs (like Apollo client) have built-in client-side caching by default. This could make simply querying the data you need everywhere viable and not that much of a performance hit. But this is still not the best approach. The best approach for the query is to call the custom hook in top level and store the response in context. (Keeping in mind that the query needs to be refetched when changes are made in the settings page).
Here is a comparison:
| Feature | Raw Apollo Hook (Your current setup) | Context + Apollo Hook (Recommended) |
|---|---|---|
| Network Efficiency | High (Apollo caches requests) | High (Apollo caches requests) |
| Render Efficiency | Medium (Hook logic runs in every component) | Maximum (Logic runs once at top level) |
| Dev Experience | Medium (Must handle loading everywhere) |
Excellent (Data is just "there") |
| Consistency | Good | Best (Single source of truth) |