Search code examples
reactjsreact-context

React Context, how to update context in one branch, to use in another branch


Can I use the React Context API to manage the global state for itemsInCart, allowing Product to update the context, and only Nav to use and re-render. I don't want to re-render the whole app on change.

Reading the React docs, I see Context users need to be downstream from the providers, so not sure this will be possible

Code (dramatically simplified):

 function NavBar () {
    const [itemsInCart, setItemsInCart] = useState(0)

    return (
      <button onClick={openCart}>{itemsInCart}</button>
    )
  }

 function Product() {

    function incrementCart () {
      ???
    }

    return (
      <button onClick={() => incrementCart}>add product to cart</button>
    )
  }

  function App () {
    return (
      <NavBar/>
      <Router>
        <Product/>
      </Router>
    )
  }

Solution

  • You want to use useContext to do it.

    A component calling useContext will always re-render when the context value changes. If re-rendering the component is expensive, you can optimize it by using memoization.

    For example:

    export const CartContext= React.createContext();
    
    export const CartProvider = ({ children }) => {
      const [itemsInCart, setItemsInCart] = useState(null);
    
      return (
        <CartContext.Provider
          value={
            itemsInCart
          }
        >
          {children}
        </CartContext.Provider>
      );
    };
    

    Then in some function you can use to get an update the cart:

      const {itemsInCart, setItemsInCart} = useContext(CartContext);
    

    And lastly, update the Provider wrapping like:

      function App () {
        return (
         <CartProvider>
          <NavBar/>
          <Router>
            <Product/>
          </Router>
         </CartProvider>
        )
      }