【问题标题】:Parent component re-rendering child components multiple times ReactJS父组件多次重新渲染子组件ReactJS
【发布时间】:2016-12-02 10:13:03
【问题描述】:

我对 React 比较陌生,所以仍在努力学习最佳实践等。

我目前正在创建一个仪表板样式的应用程序,该应用程序具有多个显示各种数据的“小部件”。我有一个父组件“仪表板”,它呈现每个“小部件”组件(它们是哑组件),数据通过道具传递。

现在我遇到的问题是,在我的“仪表板”组件中,我正在执行一个 ajax 调用来获取每个小部件的数据,在每个 ajax 调用成功后,我正在调用 setState() 并将数据推入。

从设计模式的角度来看,这似乎是正确的,但显然调用 setState 会导致级联重新渲染,因此在我的情况下每个小部件都被重新渲染 10 次(因为我有 10 个小部件)。

我在这里做错了什么?我的应用现在是 Flux 或 Redux 类型架构的候选者吗?

编辑:下面的代码

父组件

/**
 * Ajax calls (10 different calls, wont list them, all very similar)
 */
getRecent: function (url, limit) {

    $.get(url, function (res) {

        var data = res.response;
        var products = [];

        if (data.itemListInfo.numberOfItems > 0) {
            for (var i = 0, j = limit; i < j; i++) {
                products.push({
                    name: data.userItems[i].product.name,
                    itemCode: data.userItems[i].product.itemCode,
                    img: data.userItems[i].product.thumbnailImage,
                });
            }

        }

        // Obviously this is causing render() to fire
        this.setState({
            recent: {
                numberOfItems: data.itemListInfo.numberOfItems,
                products: products
            }
        });

        setTimeout(function () {
            $('#account-recent .loading').fadeOut();
        }, 500);

    }.bind(this));

},
componentDidMount: function () {
    this.getReviews(this.config.reviews.url); // causes a render()
    this.getRecent('/api/user/purchases/list', 3); // causes a render()
    this.getRecommended('/api/user/recommendations/list', 3); // causes render()
    this.getPreferences('/api/user/preferences/list'); //causes render()
    // More ajax calls here....
},
render: function () {
    return (
        <Reviews data={this.state.reviews}/>
        <Recommended data={this.state.recommended}/>
        <RecentlyPurchased data={this.state.recent}/>
        <Preferences data={this.state.preferences}/>
    )
}

如果我将 console.log('rendering...') 放在其中一个子渲染方法中,它会显示多次,具体取决于它在 ajax 调用堆栈中的位置

【问题讨论】:

  • 你能分享你的代码吗?
  • 如果您确实需要点击 5 个 API(或一个 API 五次)来获取每个小部件的信息,那么在每个小部件中执行此操作。如果您可以将所有内容集中在一起,请在父母中进行。或者您可以使用Promise.all([]) 并等待所有请求返回,然后再更新状态。但真的,是的,把它放在 redux 商店里。
  • @DavidGilbertson 是的,我最初开始在单个组件中进行调用,但后来在某处读到所有数据最好通过 props 从父组件传递到“哑”组件,所以走这条路

标签: javascript ajax reactjs


【解决方案1】:

正如您所提到的,您将有关所有小部件的信息存储在父小部件中,因此当状态更改时,它会触发子更新,这是预期的行为。由于没有代码,因此很难识别您的情况,但有一些适合您:

  1. 实现shouldComponentUpdate 方法,因此小部件只有在收到更改的道具时才会更新。

  2. 执行 1 次 ajax 调用以获取所有小部件的信息,因此您只需 1 次调用和 1 次更新。

  3. 您可以使用 redux 或 mobx 并将您的小部件连接到一个状态,然后仅当传递给小部件的道具发生更改时才会重新渲染。

如果您编写更多代码会更容易提供帮助。

【讨论】:

  • 嗨,Ross - 是的,我明白它为什么这样做,我现在正在工作,所以会在几分钟内添加一些代码。我尝试实现 shouldComponentUpdate 但组件从未接收到初始数据(因为我猜 setState 在它击中那个小部件之前已经发生了 3 或 4 次)。不幸的是,我必须调用多个端点来获取不同的数据。也许我可以做每个 AJAX 调用然后推入一个数组,然后当所有 ajax 调用完成时,我可以设置一次状态。似乎矫枉过正?我会发布代码
猜你喜欢
  • 2018-08-12
  • 2019-06-01
  • 1970-01-01
  • 2020-02-13
  • 2023-04-11
  • 2020-06-20
  • 2021-12-01
  • 2019-01-01
  • 2019-02-26
相关资源
最近更新 更多