0

The problem is that when I call the dispatch function of the useReducer hook declared in the Context SelectedMealContext , the<Item/> gets re-evaluated even if I am not changing the state of useReducer in the context.

My <MealLists/> component has array of objects and renders <Item/> by map() from mealsData .

The component tree is <MealLists/> > <Item/> > <ItemAmount/> > <Input/>

Only the <Item/> has called the Context as useContext(SelectedMealContext)

Note : <Input/> component is export default React.memo(Input) thats why it is re-evaluated only when <App/> loads .

When the app loads first the all of logged messages get shown ,Now on first click of Add button I get the re-evaluated messages again but after the first click and so on I don't get further re-evaluation as shown below in images:

The Console is cleared after App loaded and each call of dispatch function by click Add button **

When app loads :

** enter image description here

**

At first click :

**

enter image description here

**

At second click :

**

enter image description here

import Item from './item';
import Card from '../UI/card'
import styles from './mealists.module.css'
const mealsData = [
    {
        id: 'm1',
        name: 'Sushi',
        description: 'Finest fish and veggies',
        price: 22.99,
      },
      {
        id: 'm2',
        name: 'Schnitzel',
        description: 'A german specialty!',
        price: 16.5,
      },
      {
        id: 'm3',
        name: 'Barbecue Burger',
        description: 'American, raw, meaty',
        price: 12.99,
      },
      {
        id: 'm4',
        name: 'Green Bowl',
        description: 'Healthy...and green...',
        price: 18.99,
      },
]
const MealLists =()=>{
    console.log("Meals Lists components");
    return (
        <>
        <Card card={styles.meal} style={{marginTop: '200px'}}>
        <ul >
            {mealsData.map((mealItem)=>{
            return <Item 
                key={mealItem.id}
                id={mealItem.id}
                mealName={mealItem.name} 
                mealDescription={mealItem.description}
                mealPrice={mealItem.price}/>
            })}
        </ul>
        </Card>
        </>
        
    )
}
export default MealLists; 

My Context SelectedContext is as :

import React,{useReducer} from 'react'
export const SelectedMealContext = React.createContext();
const SelectedDishesReducer =(state,action)=>{
  if(action.type ==='increment'){
    console.log("Increment")
  }else if(action.type === 'decrement'){
    console.log("Decrement")
  }else if(action.type === "new_meal"){
    console.log("New Meal")
    console.log(action.data)
  }
}
const SelectedDishes = []

const SelectedMealContextProvider= (props) => {
  console.log("Selected Meals Context evaluated");
  const [SelectedMeals , dispatchAction ] = useReducer(SelectedDishesReducer,SelectedDishes);
  console.log(SelectedMeals);
  return (
    <SelectedMealContext.Provider
        value={{
          SelectedMeals : SelectedMeals,
          onIncrement : dispatchAction,
          onDecrement : dispatchAction,
          onAdd : dispatchAction
        }}
        >{props.children}
    </SelectedMealContext.Provider>
  )
}

export default SelectedMealContextProvider ;

and the subscriber component is <Item/>

import React ,{useContext} from 'react'
import styles from './item.module.css'
import ItemAmount from './ItemAmount'
import {SelectedMealContext} from '../DataContext/SelectedContext'
const Item =(props )=>{
    console.log(`Item component for : ${props.id}`)
    const Add = useContext(SelectedMealContext).onAdd;
    const AddSelectedItems =(amount)=>{
        console.table(props.id , props.mealName ,props.mealPrice)
        let selectedDish = {
            mealId: props.id,
            mealName: props.mealName,
            price: props.mealPrice,
            number_of_meal : amount}
        Add({type: "new_meal",data: selectedDish})
        // console.log(`SelectedDish : ${selectedDish.number_of_meal}`)


    }
    return(
        <li  key={props.id} className={styles.meal}>
            <div>
            <h1 className={styles.mealName}>{props.mealName}</h1>
            <h3 className={styles.description}>{props.mealDescription}</h3>
            <h2 className={styles.price}>{props.mealPrice}</h2>
            </div>
            <ItemAmount AddSelectedItems={AddSelectedItems}/>
        </li>
    )
}
export default Item ;
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Muhammad Mehdi
  • 531
  • 1
  • 5
  • 14

0 Answers0