为什么shouldComponentUpdate说当前道具是React中的新道具

Why is shouldComponentUpdate saying current props are new props in React?

本文关键字:React 新道具 shouldComponentUpdate 为什么      更新时间:2023-09-26

我正在使用Redux,但不确定这是否是原因。

我有这样的代码

<Page>
  <AnotherChild />
  <Pricing quotes={this.props.item.quotes} />
</Page>

<Pricing>有一个子组件,它在输入更改时触发调度,从而更新商品的价格。

<Pricing>具有以下特性:

shouldComponentUpdate(nextProps, nextState) {
  console.log(nextProps.quotes[0].value, this.props.quotes[0].value);
}

假设输入有10,我高亮显示所有并按5,日志显示下一个和当前道具值的5

弄不明白是怎么回事。我想我需要在某个时候看到10->5的日志,因为它从10开始,不能神奇地从父母那里切换,对吧?

编辑

这是一个触发道具更改的代码块。

_updateDiscountAmount() {
  var discountAmount = +this.refs.discount_amount.getValue();
  var quotes = this.props.quotes.map(quote => {
    var promoPrice = quote.value;
    if (Number.isNaN(discountAmount)) {
      discountAmount = 0;
    }
    quote.percentage = discountAmount;
    promoPrice = (promoPrice - (promoPrice * discountAmount/100)).toFixed(2);
    return quote;
  });

  this.props.dispatch({
    type: 'CURRENT_PAGE_UPDATE',
    data: {
      discount_amount: discountAmount,
      quotes
    }
  });
},

当你的nextProps看起来和this.props一样时,通常你会在某个地方无意地改变道具。例如:

// this.props.quotes = [ { discount : 5 }, { discount : 3}];
var quote = this.props.quotes[0];
console.log(quote.discount);               // 5
quote.discount = 10;                       // (!) this also updates props
console.log(this.props.quotes[0].discount); // 10

要修复,请在更新之前复制对象,如下所示:

var newQuotes = this.props.quotes.map(quote => {
  // Copy object
  var newQuote = Object.assign({}, quote);
  ...
  newQuote.percentage = discountAmount;
  ...
  return newQuote;
});
上面的

@wintvelt给出了答案,所以如果他写进去,我会标记它。

基本上,上面的代码是失败的。即使我正在映射到一个新的数组,我也在更改不可变的内容。

为了解决这个问题,我所需要做的就是在修改之前在循环中复制quote

即:

var quotes = this.props.quotes.map(quote => {
  // Copy the object here
  quote = Object.assign({}, quote);
  var promoPrice = quote.value;
  if (Number.isNaN(discountAmount)) {
    discountAmount = 0;
  }
  quote.percentage = discountAmount;
  promoPrice = (promoPrice - (promoPrice * discountAmount/100)).toFixed(2);
  return quote;
});