【问题标题】:Why won't my react component re-render when componentShouldUpdate returns true?为什么当 componentShouldUpdate 返回 true 时我的 react 组件不会重新渲染?
【发布时间】:2025-12-29 07:20:08
【问题描述】:

我无法理解生命周期挂钩在我的 React 应用程序中的工作方式。我有一个应用程序,我在我的渲染方法中将一些道具传递给我的分页组件,如下所示:

<Pagination
  totalRecords={this.state.blogPosts.length}
  pageLimit={5}
  pageNeighbours={2}
  onPageChanged={() => {console.log('page changed');}}
/>

在 Pagination 构造函数中,我打印出 prop 值。

const { totalRecords = null, pageLimit = 30, pageNeighbours = 0 } = props;
console.log('totalRecords=', totalRecords); 

它打印出 0。

很公平,我还没有获取我的博客文章。所以在 componentDidMount 中,我会像这样获取博客文章:

componentDidMount() {
  axios.get('/blogs').then(
    response => {
      if (response.data) {
        const entries = Object.entries(response.data);
        this.setState({ 
          blogPosts: entries.map(p => Object.assign({id: p[0]}, {...p[1]}))
            .sort((p1, p2) => p1.updatedAt > p2.updatedAt ? -1 : 1),
        });
      }
    },
    err => {
      console.log('err=', err);
    });
}

所以现在博客文章已填充,但分页组件没有更新(即使博客本身似乎更新了)。

这是我需要一些关于 React 生命周期钩子如何工作的指导。状态改变后渲染方法不会重新运行吗?我期待 Pagination 组件被重新渲染,这次让 totalRecords 道具打印出 3(或高于 0 的某个数字)。构造函数即使重新渲染也只运行一次吗?

所以为了以防我不得不触发重新渲染,我在 componentShouldUpdate() 方法中运行了这个:

shouldComponentUpdate(nextProps, nextState) {
  console.log('this.state.blogPosts.length=', this.state.blogPosts.length);
  console.log('nextState.blogPosts.length=', nextState.blogPosts.length);
  return this.state.blogPosts.length !== nextState.blogPosts.length;
}

确实,this.state.blogPosts.length 显示 0nextState.blogPosts.length 显示 3。所以它们是不同的,我期待状态更新为 3 篇博文。如果长度不同,我返回 true,它们是,所以组件应该更新。这不意味着重新渲染吗?

无论如何,totalRecords 还是 0。我什至在 Pagination 组件中设置了一个时间间隔:

setInterval(() => {
  console.log('this.totalRecords =', this.totalRecords);
}, 5000);

在获取博客帖子并将其添加到状态后很长时间,它会打印出 0...。

为什么分页组件没有更新为 totalRecords 的新值?

【问题讨论】:

  • 贴一个Minimal, Complete, and Reproducible组件代码示例可能会更有帮助。只需几个 sn-ps 就很难知道您的组件可能还在做什么,您的初始状态可能是什么,或者您的 Pagination 组件如何处理 prop 更新。您能否同时包含Pagination 组件代码 呈现Pagination 的组件代码?区间中的this.totalRecords 是什么?真的是this.props.totalRecords吗?
  • 似乎this.totalRecords 可能是一个错字,应该是this.state.totalRecords
  • @DrewReese 同意,需要更多信息。在我看来,&lt;Pagination /&gt; 组件内部可能有一些东西导致它无法重新渲染自己。
  • 抱歉不够详细。 Desmond Hiew 的回答适用于我的情况,因此无需跟进。

标签: reactjs state react-lifecycle-hooks


【解决方案1】:

也许你忘了在Pagination 组件中使用componentWillReceiveProps

componentWillReceiveProps(nextProps) {
  this.setState({ totalRecords: nextProps.totalRecords })
}

【讨论】:

  • 成功了,戴斯蒙德。我想这意味着每次渲染组件时都不会重复调用组件构造函数。为了确定,我在构造函数中放了一个 console.log ,实际上它只被调用一次,即使 totalRecords 现在由于 componentWillReceiveProps() 正在更新。