Explain Codes LogoExplain Codes Logo

How to update React Context from inside a child component?

javascript
react
context-api
performance
Alex KataevbyAlex Kataev·Dec 1, 2024
TLDR

To skillfully update React Context inside a child component, you cleverly pass an updater function alongside the context value in your Context.Provider. For functional components, this becomes a walk in the park with the useState and useContext hooks.

Here's a basic explanation:

const MyContext = React.createContext(); const MyProvider = ({ children }) => { // I'm alive when the app starts breathing! const [value, setValue] = React.useState('Initial Value'); // I ensure the app's heart does not beat unnecessarily! const contextValue = React.useMemo(() => ({ value, setValue }), [value]); return <MyContext.Provider value={contextValue}>{children}</MyContext.Provider>; }; const MyChildComponent = () => { const { setValue } = React.useContext(MyContext); // The magic button you've been waiting for! return <button onClick={() => setValue('Updated Value')}>Update Context</button>; };

"Enrobe" the parent component with <MyProvider> and put <MyChildComponent> as a merry child to update the context from within.

Breaking down the process

Dynamic contexts in class components

For class components, there's a different trick. You'll need to create a context and set some default values, then call upon the parent's state to make the context dynamic:

class MyClassComponent extends React.Component { static contextType = MyContext; // I pledge my allegiance to MyContext! updateContext = () => { // Changing context values like a boss! this.context.setValue('Updated Value for Class Component'); } render() { // The class way to update context! return <button onClick={this.updateContext}>Update Context</button>; } }

Wisdom of useMemo

useMemo is the often-overlooked genius who ensures your components don't re-render unless absolutely necessary. Trust me; it's a lifesaver with context!

const contextValue = React.useMemo(() => ({ value, setValue }), [value]);

The TypeScript hero

TypeScript serves as your trusty sidekick, preventing villainous bugs with the power of type safety. Define an interface for your context state and plunge head-first into coding with robust autocomplete and compile-time error checks.

interface MyContextState { value: string; setValue: (newValue: string) => void; } const MyContext = React.createContext<MyContextState | null>(null);

Keep in mind

  • Always have default values for your context. Trust me; you don't want any unhandled exceptions crashing your party!
  • If using class components, update the context using the Consumer or contextType.
  • Punctuate UI events with context updates.
  • To better follow code quality standards, it's a good idea to use linter tools like ESLint.
  • Be a performance ninja; understand how context updates affect component re-renders!

Deeper insights

Considering global state

Manage global state with context? Why not! Just be mindful of complex logic scenarios demanding middleware or other patterns for seamless operation.

Be aware of pitfalls

  • Inefficient structuring can give you an unwanted taste of the "prop drilling" soup.
  • Too much context can hamper performance.
  • Trying to handle everything with context might divert your focus from proper state encapsulation. Sometimes a local state or a state management library is your best bet.

Other considerations

  • For an organized codebase, splitting into separate contexts can be an elegant solution.
  • Reign in context updates to prevent performance degradation.
  • Make use of React's latest context API for flexible and efficient coding. Don't forget to stay in sync with updates!