Closed basile-parent closed 1 month ago
In our use, if our data changes, we sometimes have to call forceUpdate() on the Grid instance to make it re-render. I think there are some optimizations in the Grid code to minimize the calls to render(). Simply reducing the rowCount may not be enough to trigger a rerender. This is even worse if you are using variable-height rows where you may have to call Grid.recomputeGridSize() after a data change.
I want to ask when to call forceUpdate() ? How to use it ? I'm not going to use forceUpdate()
export default class VirtTable extends React.Component {
constructor(props){
super(props);
}
_cellRenderer = ({columnIndex, key, rowIndex, style}) => {
return (
<div>{this.props.option.dataSource[rowIndex][columnIndex]}</div>
);
}
componentDidUpdate(){
//Do you use it here
// ....this.forceUpdate()
}
render(){
return(
<AutoSizer>
{({ height, width }) => (
<MultiGrid
cellRenderer={this._cellRenderer}
columnWidth={146}
columnCount={this.props.option.dataSource[0].length}
fixedColumnCount={1}
fixedRowCount={0}
height={height}
rowHeight={60}
rowCount={this.props.option.dataSource.length}
width={width}
style={STYLE}
styleBottomLeftGrid={STYLE_BOTTOM_LEFT_GRID}
styleTopLeftGrid={STYLE_TOP_LEFT_GRID}
styleTopRightGrid={STYLE_TOP_RIGHT_GRID}
/>
)}
</AutoSizer>
)
}
}
In our component that wraps a MultiGrid (equivalent to your VirtTable), we added a dataFreshness: any prop. If you do that, the user of VirtTable would then change this value whenever the data changes. Then in the componentWillReceiveProps() lifecycle method, check to see if dataFreshness has changed. If so, call MultiGrid.forceUpdateGrids(). You will have to get a ref to the MultiGrid in order to call this method. That forces a rerender pass on all Grids contained by the MultiGrid. That should ensure that your new rows are rendered. This technique works great when we are fetching new data and doing sorting and filtering since the rowCount may or may not change.
I would try to update to 9.19.x version of react virtualized. any prop changes should trigger a re-render.
however, forceUpdate
and forceUpdateGrids
are also viable alternatives.
hope that helps!
@koalajun I would recommend calling forceUpdate
when you data updates.
ex:
fetch('/endpoint')
.then(data => data.json())
.then(data => {
this.setState({ gridProps: data }, () => this.gridRef.forceUpdate());
})
@wuweiweiwu: Didn't work. I have a similar issue working with List component and the input data is filtered by a outer component.
Used both forceUpdate and forceUpdateGrids, none of them worked
Having similar problems with client side filtering. All of this has forced me to learn this api well. But yeah, still can't figure out how to update this.
@kpennell: Share the sample code here. I was able to fix this using rowRenderer function. Inside the rowRenderer function, we need to use the filtered data only.
In componentDidUpdate:
componentDidUpdate() {
this.List.current.forceUpdate();
this.List.current.forceUpdateGrid();
}
@krayush thx for this. I'll give it a try.
Hi, I'm seeing a similar issue when data changes after I have set isScrollingOptOut = true
. My current workaround is to refresh the grid onComponentUpdate
:
We've written a wrapper around VirtualGrid
due to changes proposed in #1377, however this is essentially the same:
this._cellMeasurementCache.clearAll();
this._gridRef.recomputeGridSize();
Hello, I have a problem using the Grid component. I doing an iTunes like software and I'm trying to implement a search function.
The datas are well filtered, the props are updated in all components but the rendering is very strange. If the result of the filtering return 3 rows (like in the below image), the grid render the first 3 rows of the initial data set and not taking into account the new data set.
My code :
Do you have any clue on why the grid is rendering its initial datas filtered on the
n
first rows an not the filtered datas its receives with props ?Thank you.