I am changing some values of rendered items in List component. But the list isn't showing my change. I am making a workaround using forceUpdateGrid. But I should detect in my props if any of my items was changed.
Detect if any value of items in current RENDERED RANGE changed, and re-render them.
I am using a List component and I saved as virtualList ref.
componentWillReceiveProps(nextProps) {
const startIndex = this.virtualList.Grid._rowStartIndex;
const stopIndex = this.virtualList.Grid._rowStopIndex;
this.shouldForceList = compareItems(startIndex, stopIndex, this.pros, nextProps); // comparte item list.
}
componentDidUpdate() {
if (this.shouldForceList && this.virtualList) {
this.virtualList.forceUpdateGrid();
}
}
I am changing some values of rendered items in List component. But the list isn't showing my change.
The reason for this is explained briefly here. forceUpdateGrid is an acceptable solution for this. A unique property that changes when your items changes (such as an incremented counter) would also work.
Detect if any value of items in current RENDERED RANGE changed, and re-render them.
If item changes invalidate their size then you should _always_ inform List (by calling recomputeRowHeights, which will also re-render for you). If it only affects their visuals, not size, then calling forceUpdateGrid is sufficient.
Detect if any value of items in current RENDERED RANGE changed, and re-render them.
You can do this with the onRowsRendered property mentioned in the docs. It will trigger each time the visual range of rows change.
So try something like this:
_onRowsRendered({ startIndex, stopIndex }) {
this._startIndex = startIndex
this._stopIndex = stopIndex
}
componentWillReceiveProps(nextProps) {
// Note that this may be expensive depending on how often this method fires.
// It may be cheaper to calculate this wherever your items are changing.
const hasChanged = compareItems(
this._startIndex,
this._stopIndex,
this.pros,
nextProps
);
if (hasChanged) {
// This property will trigger a re-render of List since it's changed.
this._listChangeCounter++
}
}
render() {
return (
<List
listChangeCounter={this._listChangeCounter}
onRowsRendered={this._onRowsRendered}
{...this.props}
/>
)
}
I am going to close this issue because I believe you have all of the tools you need to do what you're looking for. 馃槃
Thanks for your quickly answer, and it works.
@bvaughn Follow-up question: onRowsRendered only gets called when the indexes rendered change, but not when the items at those indexes change (are re-rendered), correct?
Yup. RV doesn't know anything about the second case.
Ok! Just wondering. I think just attaching a ref to the rowRenderer is the best solution for my usecase. Thanks!
Actually in my case the items inside the list are only updated if I scroll the element or resize the window, the counter thing doesn't work
Most helpful comment
The reason for this is explained briefly here.
forceUpdateGridis an acceptable solution for this. A unique property that changes when your items changes (such as an incremented counter) would also work.If item changes invalidate their size then you should _always_ inform
List(by callingrecomputeRowHeights, which will also re-render for you). If it only affects their visuals, not size, then callingforceUpdateGridis sufficient.You can do this with the
onRowsRenderedproperty mentioned in the docs. It will trigger each time the visual range of rows change.So try something like this:
I am going to close this issue because I believe you have all of the tools you need to do what you're looking for. 馃槃