我有一个网格,可以呈现可变高度的卡片.
为了获得卡片的高度,我将卡片包装在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>
);
}
}
Run Code Online (Sandbox Code Playgroud)
我知道setState()调用render,并且调用函数来改变内部状态render通常会导致无限循环.
在我的代码中,render调用一个更新this.state.cardHeights数组的函数,并且它的子组件的呈现Card间接依赖于this.state.cardHeights,因为this.state.paddings它直接依赖于它是基于cardHeights on计算的componentDidUpdate().
但是,我无法在Card不渲染的情况下获得组件的高度,因此我能想到的唯一方法是制作padding一个prop卡片和组件状态,然后在渲染后更改状态.
我的问题是:
不知怎的,即使我在渲染中改变状态,我的代码也没有导致无限循环,但这是一个更好的方法吗?
clearInterval()在我的componentDidUpdate()功能里面似乎没有用.我把一个print语句放在一边*A*,即使满足if条件并且clearInterval()可以调用它也会保持打印.这可能是因为我的状态突变吗?
在这种情况下,您应该在更新状态之前检查以前的值和新值是否相同。我希望您的身高不会因每次渲染而更新。因此,您可以进行检查updateCardheights以确定是否存在实际更改,然后更新状态。这确保它不会更新冗余更新的状态。但是如果在每次渲染时您的状态都将被更新,那么问题将保持不变。
updateCardHeights(index, height) {
if(this.state.cardHeights[index] !== height) {
this.setState(prevState => ({
cardHeights: {
...prevState.cardHeights,
[index]: height,
},
}));
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
20793 次 |
| 最近记录: |