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:
- Listing the context (both
context
andcontext.items
) as a dependency in the useEffect
- this resulted in the component not updating when the values changed
- 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.
- 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;