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)
。在这里阅读更多:不完全是我所做的,但我在这里和那里添加了更多的条件检查。