Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 当状态依赖于render时,如何避免render()中的setState()_Reactjs - Fatal编程技术网

Reactjs 当状态依赖于render时,如何避免render()中的setState()

Reactjs 当状态依赖于render时,如何避免render()中的setState(),reactjs,Reactjs,我有一个网格,可以渲染不同高度的卡片 为了获得卡片的高度,我将卡片包装在ReactHeight()中,这样当高度准备好时,我就可以向它传递回调函数 我将卡片高度保存在组件状态的数组中,并在报告卡片高度时更新 当所有高度都可用时,我根据高度计算填充,然后render传递到卡片 在简化版本中,它看起来是这样的 class Grid extends Component { constructor() { ... this.state = { cardHeights: {}, pad

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

为了获得卡片的高度,我将卡片包装在
ReactHeight
()中,这样当高度准备好时,我就可以向它传递回调函数

我将卡片高度保存在组件
状态
的数组中,并在报告卡片高度时更新

当所有高度都可用时,我根据高度计算填充,然后
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>
    );

  }
}
<代码>类网格扩展组件{ 构造函数(){ ... this.state={cardHeights:{},paddings:[]};//初始状态 } componentDidUpdate(){ 常数i=设置间隔(()=>{ 如果(所有高度都准备好了){ //…计算填充物 此.setState(填充:计算填充); 间隔时间(i); } }, 100); //*A* } updateCardHeights(索引,高度){ this.setState(prevState=>({ 卡片高度:{ …普雷维斯塔·卡德海茨, [指标]:身高,, }, })); } render(){ //索引=卡片的索引类似于1 2 3 // 4 5 6 // 7 8 9 // 10 11 12 // ... 返回( this.updateCardHeights(索引,高度)} ); } } 我知道
setState()
调用
render
,调用函数改变
render
中的状态通常会导致无限循环

在我的代码中,
render
调用更新
this.state.cardhights
数组的函数,其子组件
Card
的呈现间接依赖于
this.state.cardhights
,因为它直接依赖的
这个.state.paddings
是根据
componentdiddupdate()
上的卡片高度计算的

但是,如果不渲染,我无法获得
组件的高度,因此我能想到的唯一方法是将
填充
a
属性
设置为卡和组件的状态,然后在渲染后更改状态

我的问题是:

  • 不知何故,我的代码并没有导致一个无限循环,即使我正在改变渲染内部的状态,但这是一个更好的方法吗

  • clearInterval()
    在我的
    componentdiddupdate()函数中
    。我在
    *a*
    部分中放置了一个print语句,即使满足if条件并且假定调用了
    clearInterval()
    ,它也会继续打印。这是不是因为我的状态不好


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

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

    关于上述问题,我有以下解决方案。
    只需在render函数外部指定事件处理程序。不要忘记在构造函数中绑定事件处理程序。之后,您可以在渲染函数中调用该事件处理程序

    这里的
    索引是什么?也许您可以使用
    shouldComponentUpdate(nextrops,nextState)
    。在这里阅读更多:不完全是我所做的,但我在这里和那里添加了更多的条件检查。