react-tiny-virtual-list
react-tiny-virtual-list copied to clipboard
setState in onItemsRendered
I need to keep track of which items are visible outside of the VirtualList component. However, if I call setState in onItemsRendered, then React will correctly complain:
Warning: Cannot update during an existing state transition (such as within `render` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`.
Is there are correct pattern for this? Ideally VirtualList would have a renderProp style prop that could look like ({ RenderedListNode, startIndex, endIndex}) => Node.
This is the code, it works in this simple example but causes the React warning and issues in more complicated code:
// @flow
import React from "react";
import VirtualList from "react-tiny-virtual-list";
const data = Array(1000)
.fill(0)
.map((item, index) => index);
type Props = {};
type State = {
currentlyVisibleIndex: number,
};
class Test extends React.Component<Props, State> {
state = { currentlyVisibleIndex: 0 };
onItemsRendered = ({ startIndex, stopIndex }) => {
const { currentlyVisibleIndex } = this.state;
if (currentlyVisibleIndex !== startIndex) {
this.setState({ currentlyVisibleIndex: startIndex });
}
};
render() {
const { currentlyVisibleIndex } = this.state;
return (
<div>
<div>Currently Visible: {currentlyVisibleIndex}</div>
<VirtualList
width="100%"
height={600}
itemCount={data.length}
itemSize={50}
overscanCount={0}
renderItem={({ index, style }) => (
<div key={index} style={style}>
{data[index]}, Row: #{index}
</div>
)}
onItemsRendered={this.onItemsRendered}
/>
</div>
);
}
}
export default Test;
I just setState within a setTimeout of 1ms to solve this.