reactjs - 当状态依赖于 render 时,如何避免 render() 内的 setState()

标签 reactjs

我有一个网格,可以渲染可变高度的卡片。

为了获取卡片的高度,我将卡片渲染在 ReactHeight 中。 ( https://github.com/nkbt/react-height ),这让我可以在高度准备好时向其传递回调函数。

我将卡片高度保存在组件 state 的数组中,我会在报告卡片高度时更新它。

当所有高度都可用时,我根据高度计算填充,即 render传递到卡片

在简化版本中,它看起来像这样。

class Grid extends Component {
  constructor() {
    ...
    this.state = { cardHeights: {}, paddings: [] }; //initial state
  }

  componentDidUpdate() {
    const i = setInterval(() => {
      if (all heights are ready) {
        // ...calculate paddings
        this.setState(paddings: calculatedPaddings);

        clearInterval(i);
      }
    }, 100);
    // *A*
  }

  updateCardHeights(index, height) {
    this.setState(prevState => ({
      cardHeights: {
        ...prevState.cardHeights,
        [index]: height,
      },
    }));
  }

  render() {
    // index = cards are indexed like 1   2  3
    //                                4   5  6
    //                                7   8  9
    //                                10 11 12
    //                                     ...
    return (
      <ReactHeight onHeightReady={ height => this.updateCardHeights(index, height) }
         <Card padding={this.state.paddings[index]}/>
      </ReactHeight>
    );

  }
}

我知道setState()来电 render ,并调用一个函数来改变 render 内的状态通常会导致无限循环。

在我的代码中,render调用更新 this.state.cardHeights 的函数数组,及其子组件的渲染,Card ,间接取决于this.state.cardHeights ,自 this.state.paddings它直接依赖的是根据componentDidUpdate()上的cardHeights计算的.

但是,我无法获取 Card 的高度组件而不渲染它,所以我能想到的唯一方法是制作 padding一个prop到组件的卡片和状态,然后渲染后改变状态。

我的问题是:

  1. 即使我在渲染内更改状态,我的代码也不会导致无限循环,但有更好的方法吗?

  2. clearInterval()在我的里面componentDidUpdate()功能似乎不起作用。我在*A*中放置了一条打印语句部分,即使满足 if 条件并且 clearInterval() ,它也会继续打印据说被称为。难道是我状态突变导致的?

最佳答案

在这种情况下,您应该在更新状态之前检查先前的值和新值是否相同。我希望你的高度不会因每次渲染而更新。因此,您可以检查updateCardheights以确定是否存在实际更改,然后更新状态。这确保它不会更新冗余更新的状态。但如果在每次渲染时您的状态都会更新,那么问题将保持不变。

updateCardHeights(index, height) {
 if(this.state.cardHeights[index] !== height) {
  this.setState(prevState => ({
   cardHeights: {
     ...prevState.cardHeights,
     [index]: height,
   },
  }));
 }
}

关于reactjs - 当状态依赖于 render 时,如何避免 render() 内的 setState(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44037611/

相关文章:

reactjs - 在 useEffect 中访问 Formik 的 setValues

html - 导航栏边距的间距不起作用 react

javascript - 使用 redux 和 React-router 进行深度链接的推荐方法

javascript - React 不会在 map 函数中渲染

reactjs - 如何为未单击的元素返回基本类名React

javascript - 使用 React 构建一个安静的 Web 应用程序并具有多个角色

javascript - Redux 状态下的复杂对象

javascript - ReactJS中箭头函数有什么用?

html - 如何使用 ant-design 在布局中拉伸(stretch)父元素宽度

reactjs - 如何根据请求路由中的参数实现条件路由?