Home > Software design >  How to use useEffect correctly with useContext as a dependency
How to use useEffect correctly with useContext as a dependency

Time:09-23

I'm working on my first React project and I have the following problem. How I want my code to work:

  • I add Items into an array accessible by context (context.items)
  • I want to run a useEffect function in a component, where the context.items are displayed, whenever the value changes

What I tried:

  1. Listing the context (both context and context.items) as a dependency in the useEffect
  • this resulted in the component not updating when the values changed
  1. Listing the context.items.length
  • this resulted in the component updating when the length of the array changed however, not when the values of individual items changed.
  1. wraping the context in Object.values(context)
  • result was exactly what I wanted, except React is now Complaining that *The final argument passed to useEffect changed size between renders. The order and size of this array must remain constant. *

Do you know any way to fix this React warning or a different way of running useEffect on context value changing?

CodePudding user response:

You can try passing the context variable to useEffect dependency array and inside useEffect body perform a check to see if the value is not null for example.

CodePudding user response:

You can start by creating your app context as below, I will be using an example of a shopping cart

import * as React from "react"

const AppContext = React.createContext({
  cart:[]
});

const AppContextProvider = (props) => {
  const [cart,setCart] = React.useState([])

  const addCartItem = (newItem)=>{
    let updatedCart = [...cart];
    updatedCart.push(newItem)
    setCart(updatedCart)
    
  }
  
  return <AppContext.Provider value={{
    cart
  }}>{props.children}</AppContext.Provider>;
};

const useAppContext = () => React.useContext(AppContext);

export { AppContextProvider, useAppContext };

Then you consume the app context anywhere in the app as below, whenever the length of the cart changes you be notified in the shopping cart

import * as React from "react";
import { useAppContext } from "../../context/app,context";

const ShoppingCart: React.FC = () => {
  const appContext = useAppContext();

  React.useEffect(() => {
    console.log(appContext.cart.length);
  }, [appContext.cart]);
  return <div>{appContext.cart.length}</div>;
};

export default ShoppingCart;
  • Related