即使使用 React.memo,更改子项的道具是否总是重新渲染父项?

时间:2021-03-03 20:29:56

标签: javascript reactjs

我试图阻止模态元素在它应该不可见时重新渲染。 我正在学习的课程通过将组件转换为基于类的组件并使用 shouldComponentUpdate() 来做到这一点,但我想检查使用 React.memo() 是否也做了同样的事情。

我试过了,但没有,但我不知道为什么。

不应该渲染的组件是这样的:

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);

由谁管理

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;

使用 BuildControls 我改变了 Ingredients 状态;但不是我传递给模态的道具,purchasingpurchaseHandler

即使 Modal 本身在 React.memo() 之下,更改我传递给它的孩子的成分道具是否总是提示重新渲染?

1 个答案:

答案 0 :(得分:0)

您正在更改传递给 Modal 的道具之一 - children 道具。它通过将子元素添加到反应元素来隐式传递。由于您正在更改子元素,因此会导致重新渲染。