【问题标题】:react lifecycle method - correct way to filter反应生命周期方法 - 过滤的正确方法
【发布时间】:2021-04-04 14:21:53
【问题描述】:

我是新来的反应。我有一个产品页面组件,它是显示特定产品的页面。我想要做的是这个 ProductPage 在 products 中找到特定的产品(这是一个存储为 props 的对象数组)并将其保存为状态,然后再渲染出来。

我收到了这些错误。我无法从数组中过滤掉单个产品。

1) currentProduct is not defined.
2)Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

我应该使用哪种生命周期方法来解决这个问题?我很迷惑。谁能给我解释一下?

在我的 ProductPage.js 中,

import React, { Component } from 'react';
import { connect } from 'react-redux';

class ProductPage extends Component {
    constructor(props) {
        super(props)

        this.state = {
            product: [],
            productId: this.props.match.params._id,
        }

      this.productsFiltering = this.productsFiltering.bind(this);
    }

    // update the state so that a product can be rendered
    componentDidUpdate() {
        const currentProduct = this.productsFiltering(this.state.productId);
        this.setState({
            product: currentProduct,
        })
    }
    
    // find a product based on the Id 
    // pass the _id from url to find out the single product
    productsFiltering = (productId) => {
        const productArray = this.props.products;
        return productArray.find(product => product._id === productId)
    }

    render() {
        // error
        const {name, price, description} = product; 
        return (
            <div>
                <span>{product.name}</span>
                <span>{product.price}</span>
                <span>{product.description}</span>
            </div>
        )
    }
}

const mapStateToProps = (state) => ({
    products: state.productsContainer,
});


export default connect(
    mapStateToProps,
)(ProductPage);

【问题讨论】:

  • 我认为你在 productsFiltering 中有错字 - 看起来应该是 productArray.find(product =&gt; product._id === productId)
  • 根本问题是您正在将道具复制到状态,而无需这样做。 ProductPage 显示产品并且不会更改,因此不需要状态。只需抓取匹配的产品并将其存储在变量中然后渲染。不需要setState()
  • @MrCode 感谢您的回答。它有很大帮助。我按照你刚才所说的,终于弄明白了!
  • @sam1024 很高兴我帮助解决了这个问题!我添加了一个答案,以便您接受并完成问题(帮助人们查看哪些问题仍需要答案)。

标签: reactjs


【解决方案1】:

如果您将代码更改为以下代码,则可以删除这两个错误:

class ProductPage extends Component {
  constructor(props) {
    super(props);

    this.state = {
      product: []
    };

    this.productsFiltering = this.productsFiltering.bind(this);
  }

  // update the state so that a product can be rendered
  componentDidUpdate() {
    const productId = this.props.match.params._id;
    if (productId && this.state.product._id != productId) {
      const currentProduct = this.productsFiltering(productId);

      if (currentProduct) {
        this.setState({
          product: currentProduct
        });
      }
    }
  }

  // find a product based on the Id
  // pass the _id from url to find out the single product
  productsFiltering = (productId) => {
    const productArray = this.props.products;
    if(productArray.length){
      return productArray.find((product) => products._id === productId);
    }
  };

  render() {
    const { name, price, description } = this.state.product || {};
    return (
      <div>
        <span>{product.name}</span>
        <span>{product.price}</span>
        <span>{product.description}</span>
      </div>
    );
  }
}

const mapStateToProps = (state) => ({
  products: state.productsContainer
});

export default connect(mapStateToProps)(ProductPage);

-- 总是检查未定义或空属性

-- 如果新状态不断变化,不要在 componentDidMount 中使用 setState

-- 避免使用直接从props 驱动的state,因为这是一种不好的做法,您可以获得stale props

【讨论】:

  • 感谢您的解释。但是第二个错误仍然存​​在。
  • @sam1024 我在componentDidMount 中添加了更多检查,这也应该可以解决第二个错误,请再试一次
【解决方案2】:

根本问题是您将 props 复制到 state,这是没有必要做的。

ProductPage 显示一个产品并且不会改变,因此不需要状态。只需抓取匹配的产品并将其存储在变量中然后渲染。不需要setState()

【讨论】:

    猜你喜欢
    • 2012-10-07
    • 2021-03-27
    • 2019-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多