【问题标题】:Creating new array vs modifing the same array in react创建新数组与在反应中修改相同的数组
【发布时间】:2020-04-20 13:32:27
【问题描述】:

以下是一段运行良好的代码,但我有一个疑问 - const _detail = detail; map 方法中的代码。在这里你可以看到我正在迭代一个数组并修改对象,然后将其设置为setState()

代码块 -

checkInvoiceData = (isUploaded, data) => {
    if (isUploaded) {
        const { invoiceData } = this.state;
        invoiceData.map(invoiceItem => {
            if (invoiceItem.number === data.savedNumber) {
                invoiceItem.details.map(detail => {
                    const _detail = detail;
                    if (_detail.tagNumber === data.tagNumber) {
                        _detail.id = data.id;
                    }
                    return _detail;
                });
            }
            return invoiceItem;
        });
        state.invoiceData = invoiceData;
    }
    this.setState(state);
};

这种方法在React 世界中是否可行,或者我应该做类似的事情 -

const modifiedInvoiceData = invoiceData.map(invoiceItem => {
  ......
   code
  ......
})

this.setState({invoiceData: modifiedInvoiceData});

每种方法的优缺点是什么?在采用其中一种方法时我需要牢记哪种情况?

【问题讨论】:

  • 经验法则:任何时候你发现你没有使用map的返回值,你最喜欢做错事。如果确实不需要使用返回值,使用forEach
  • state.invoiceData = invoiceData; 这在很多层面都是错误的。除非使用setState,否则不得改变状态
  • React 领域的惯例是创建数组或对象或任何数据的新副本。当您开始使用像 Redux 这样的状态管理库时,这一点尤其重要。
  • @ilkerkaran 这说明了什么,但没有说明原因。

标签: javascript html reactjs ecmascript-6


【解决方案1】:

你不能改变状态,相反你可以这样做:

checkInvoiceData = (isUploaded, data) => {
  if (isUploaded) {
    this.setState({
      invoiceData: this.state.invoiceData.map(
        (invoiceItem) => {
          if (invoiceItem.number === data.savedNumber) {
            invoiceItem.details.map(
              (detail) =>
                detail.tagNumber === data.tagNumber
                  ? { ...detail, id: data.id } //copy detail and set id on copy
                  : detail //no change, return detail
            );
          }
          return invoiceItem;
        }
      ),
    });
  }
};

【讨论】:

    【解决方案2】:

    也许可以试试这样的:

    checkInvoiceData = (isUploaded, data) => {
      // Return early
      if (!isUploaded) return
    
      const { invoiceData } = this.state;
    
      const updatedInvoices = invoiceData.map(invoiceItem => {
        if (invoiceItem.number !== data.savedNumber) return invoiceItem
    
        const details = invoiceItem.details.map(detail => {
          if (detail.tagNumber !== data.tagNumber) return detail
    
          return { ...detail, id: data.id };
        });
    
        return { ...invoiceItem, details };
      });
    
      this.setState({ invoiceData: updatedInvoices });
    };
    

    首先,我建议尽早返回而不是嵌套条件。

    其次,确保你没有直接改变state(例如没有this.state = state)。

    第三,将你想要改变的状态部分,而不是整个状态对象,传递给setState

    第四,返回一个新的对象实例,以便对象引用更新,以便 React 可以检测到值的变化。

    我并不是说这是做你想做的最好的方式,但它应该为你指明一个更好的方向。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-25
      • 2013-08-06
      • 1970-01-01
      • 2022-07-01
      • 2018-11-12
      相关资源
      最近更新 更多