Does changing the props of a child always re-render the parent even with React.memo? Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of Does changing the props of a child always re-render the parent even with React.memo? without wasting too much if your time.

The question is published on by Tutorial Guruji team.

I’m trying to prevent a modal element to re-render when it’s supposed to be invisible. The course I’m following does this by converting the component to a class based component and using shouldComponentUpdate() but I wanted to check if using React.memo() did the same thing.

I tried, and it doesn’t, but I’m not sure why.

The component that should not render is this:

import React , {useEffect} from 'react'

import Aux from '../../../hoc/Aux';
import Backdrop from '../Backdrop/Backdrop';
import classes from './Modal.module.css';

const Modal = (props) => {
  useEffect(() => {
    console.log('[Modal.js] useEffect')
  });

  return (
    <Aux>
      <Backdrop show={props.show} clicked={props.modalClosed} />
      <div
        className={classes.Modal}
        style={{
          transform: props.show ? 'translateY(0)' : 'translateY(-100vh)',
          opacity: props.show ? '1': '0'
        }}>
          {props.children}
      </div>
    </Aux>)
  };

export default React.memo(Modal);

Which is managed by

import React, {Component} from 'react'

import Aux from '../../hoc/Aux';
import Burger from '../../components/Burger/Burger'
import BuildControls from '../../components/Burger/BuildControls/BuildControls'
import Modal from '../../components/UI/Modal/Modal'
import OrderSummary from '../../components/Burger/OrderSummary/OrderSummary'

const INGREDIENT_PRICES = {
  salad: 0.5,
  cheese: 0.4,
  meat: 1.3,
  bacon: 0.7
}
class BurgerBuilder extends Component {

  state = {
    ingredients: {
      salad: 0,
      bacon: 0,
      cheese: 0,
      meat: 0
    },
    totalPrice: 4,
    purchasable: false,
    purchasing: false
  }

  purchaseHandler = () => {
    this.setState({purchasing: true});
  };
  purchaseCancelHandler = () => {
    this.setState({purchasing:false});
  };
  purchaseContinueHandler = () => {
    alert('You Continue!')
  };

  updatePurchaseState = (ingredients) => {
    let purchasable = false;
    for (let ingredient in ingredients){
      if (ingredients[ingredient]>0){
        purchasable = true;
        break;
      }
    }
    this.setState({purchasable:purchasable})
  }
  addIngredientHandler = (type) => {
    const oldCount = this.state.ingredients[type];
    const updatedCount = oldCount +1;
    const updatedIngredients = {
      ...this.state.ingredients
    };
    updatedIngredients[type] = updatedCount;
    const priceAddition = INGREDIENT_PRICES[type];
    const oldPrice = this.state.totalPrice;
    const newPrice = oldPrice + priceAddition;
    this.setState({totalPrice: newPrice, ingredients: updatedIngredients});
    this.updatePurchaseState(updatedIngredients);
  };
  removeIngredientHandler = (type) => {
    const oldCount = this.state.ingredients[type];
    if (oldCount <= 0)
      return;
    const updatedCount =oldCount -1;
    const updatedIngredients = {
      ...this.state.ingredients
    };
    updatedIngredients[type] = updatedCount;
    const priceAddition =INGREDIENT_PRICES[type];
    const oldPrice = this.state.totalPrice;
    const newPrice = oldPrice - priceAddition;
    this.setState({totalPrice: newPrice, ingredients: updatedIngredients});
    this.updatePurchaseState(updatedIngredients);
  };

  render () {
    const disabledInfo = {
      ...this.state.ingredients
    };
    for (let key in disabledInfo){
      disabledInfo[key] = disabledInfo[key] <= 0;
    }
    return (
      <Aux>
        <Modal show={this.state.purchasing} modalClosed={this.purchaseCancelHandler}>
          <OrderSummary
            ingredients={this.state.ingredients}
            purchaseCancelled={this.purchaseCancelHandler}
            purchaseContinued={this.purchaseContinueHandler}
            price={this.state.totalPrice} />
        </Modal>
        <Burger ingredients={this.state.ingredients}/>
        <BuildControls
          ingredientAdded={this.addIngredientHandler}
          ingredientRemoved={this.removeIngredientHandler}
          disabled={disabledInfo}
          price={this.state.totalPrice}
          purchasable={this.state.purchasable}
          ordered={this.purchaseHandler}/>
      </Aux>
    );
  }
}

export default BurgerBuilder;

With BuildControls I change the Ingredients state; but not the props I pass to modal, purchasing and purchaseHandler

Does changing the ingredients prop I pass to it’s child always prompt a re-render even when Modal itself is under React.memo() ?

Answer

You are changing one of the props you pass to Modal – the children prop. It is passed implicitly by adding children to a react element. And since you are changing the child element it will cause a re-render.

We are here to answer your question about Does changing the props of a child always re-render the parent even with React.memo? - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji