I have a grid that renders cards of variable heights.
To get the height of the cards, I render the card wrapped in ReactHeight (https://github.com/nkbt/react-height), which lets me pass a callback function to it when the height is ready.
I keep the card heights in an array in the component state, which I update as card heights get reported.
When all heights are available, I calculate the padding from the heights, which render passes to the cards
In a simplified version, it looks like this.
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>
);
}
}
I know setState() calls render, and calling a function mutating the state inside render generally leads to an infinite loop.
In my code, render calls a function that updates this.state.cardHeights array, and the rendering of its child component, Card, indirectly depends on this.state.cardHeights, since this.state.paddings that it directly depends on is calculated based on cardHeights on componentDidUpdate().
However, I cannot get the height of the Card component without rendering it, so the only way I can think of is making padding a prop to card and state of the component, and then changing the state after rendering.
My question is:
Somehow my code didn't result in an infinite loop even though I'm changing state inside render, but is a better way to do this?
clearInterval()inside mycomponentDidUpdate()function doesn't seem to work. I put a print statement in*A*part, and it keeps printing even when the if condition is met andclearInterval()is supposedly called. Can this be because of my bad state mutation?