_isRowLoaded and _loadMoreRows not getting called react virtualized
My _loadMoreRows and _isRowLoaded are not getting called, so loadedRowsMap remains empty and I am unable to identify the rows loaded to avoid making HTTP request .
Here's my complete code :
import React, { Component } from 'react';
import { connect } from 'react-redux';
import {formatDate} from '../../helper/date';
import { recentActivitiAction } from '../actions/dashboardAction';
import { BeatLoader } from 'react-spinners';
import {AutoSizer, List, CellMeasurer, InfiniteLoader, CellMeasurerCache} from 'react-virtualized';
import styles from '../../css/AutoSizer.module.css';
import Skeleton from 'react-skeleton-loader';
const STATUS_LOADING = 1;
const STATUS_LOADED = 2;
const mapStateToProps = (state) => {
return {
recentActList: state.dashboardReducer.recentActList,
activitiLoading: state.dashboardReducer.activitiLoading
}
}
const mapDispatchToProps = (dispatch) => {
return {
getRecentActivites: (postData, callback) => {
dispatch(recentActivitiAction(postData, callback));
}
};
}
class RecentActivitiComp extends Component {
constructor(props) {
super(props);
this.state = {
loadedRowCount: 0,
loadedRowsMap: {},
loadingRowCount: 0,
};
this.cache = new CellMeasurerCache({
fixedWidth: true,
defaultHeight: 100
});
this._timeoutIdMap = {};
this._isRowLoaded = this._isRowLoaded.bind(this);
this._loadMoreRows = this._loadMoreRows.bind(this);
this.renderRow = this.renderRow.bind(this);
this.onRowsRendered = this.onRowsRendered.bind(this);
this.noRowsRenderer = this.noRowsRenderer.bind(this);
}
componentWillUnmount() {
Object.keys(this._timeoutIdMap).forEach(timeoutId => {
clearTimeout(timeoutId);
});
}
componentDidMount() {
var postData = {
"userName": "admin",
"queryType": "GET_RECENT_PROJECTS",
"data": {
pageStart: 1,
pageEnd: 20
}
};
this.props.getRecentActivites(postData, this.recentActResponse.bind(this));
}
updateDimensions() {
this.cache.clearAll();
this.activitiList.recomputeRowHeights();
}
recentActResponse(response) {
if (response.status === "FAILED") {
// handle error
}
}
_fieldGenerator(row, index) {
var formattedDate = formatDate(row.lastModified),
output = '', JSX = '';
if(formattedDate) {
formattedDate = formattedDate.split('-');
output = (
<div className="project-info-value byline">
<span>{formattedDate[0]}<sup>{formattedDate[1]}</sup> {formattedDate[2]} {formattedDate[3]}</span> by <a>{row.modifiedBy}</a>
</div>
)
} else {
output = (
<div className="project-info-value byline">
<span>Invalid Date by </span> <a>{row.modifiedBy}</a>
</div>
)
}
if(row.action === "upcoming-release") {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title">{row.action}</h2>
{output}
<p className="excerpt">{row.notes}<a> Read More</a></p>
</div>
</div>
</li>
} else if(row.action === "created") {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title">{row.type} <a>{row.name}</a> {row.action}</h2>
{output}
<p className="excerpt"></p>
</div>
</div>
</li>
} else if(row.action === "modified") {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title">{row.type} <a>{row.name}</a> {row.action}</h2>
{output}
<p className="excerpt"></p>
</div>
</div>
</li>
} else {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title"><a>{row.person}</a> added to <a>{row.addedTo}</a></h2>
{output}
<p className="excerpt"></p>
</div>
</div>
</li>
}
return JSX;
}
renderRow({ index, key, style, parent }) {
var JSX = '', content = '';
const list = this.props.recentActList
const {loadedRowsMap} = this.state;
if (loadedRowsMap[index] === STATUS_LOADED) {
const row = list[index];
JSX = this._fieldGenerator(row, index);
content = (
JSX
);
} else {
content = (
<div className={styles.placeholder} style={{width: 480}} />
);
}
return (
<CellMeasurer
cache={this.cache}
columnIndex={0}
key={key}
parent={parent}
rowIndex={index}
>
{({ measure }) => (
<div key={key} style={{...style}} onLoad={measure}>
{content}
</div>
)}
</CellMeasurer>
);
}
_isRowLoaded({index}) {
const {loadedRowsMap} = this.state;
return !!loadedRowsMap[index]; // STATUS_LOADING or STATUS_LOADED
}
_loadMoreRows({startIndex, stopIndex}) {
const {loadedRowsMap, loadingRowCount} = this.state;
const increment = stopIndex - startIndex + 1;
for (var i = startIndex; i <= stopIndex; i++) {
loadedRowsMap[i] = STATUS_LOADING;
}
this.setState({
loadingRowCount: loadingRowCount + increment,
});
const timeoutId = setTimeout(() => {
const {loadedRowCount, loadingRowCount} = this.state;
delete this._timeoutIdMap[timeoutId];
for (var i = startIndex; i <= stopIndex; i++) {
loadedRowsMap[i] = STATUS_LOADED;
}
this.setState({
loadingRowCount: loadingRowCount - increment,
loadedRowCount: loadedRowCount + increment,
});
promiseResolver();
}, 1000 + Math.round(Math.random() * 2000));
this._timeoutIdMap[timeoutId] = true;
let promiseResolver;
return new Promise(resolve => {
promiseResolver = resolve;
});
}
noRowsRenderer() {
return <div className={styles.noRows}>No rows</div>;
}
onRowsRendered({overscanStartIndex, overscanStopIndex, startIndex, stopIndex}) {
const list = this.props.recentActList.length ? this.props.recentActList : ;
const {loadedRowsMap} = this.state;
console.log(startIndex, stopIndex, this.state.loadedRowCount);
// if(startIndex + 10 === list.length && this._isRowLoaded(startIndex) !== STATUS_LOADED) {
// var postData = {
// "userName": "admin",
// "queryType": "GET_RECENT_PROJECTS",
// "data": {
// pageStart: 1,
// pageEnd: 10
// }
// };
// this.props.getRecentActivites(postData, this.recentActResponse.bind(this));
// }
}
render() {
const list = this.props.recentActList.length ? this.props.recentActList : ;
const {loadedRowCount, loadingRowCount} = this.state;
return (
<div className="recent left_panel">
<div className="x_panel">
<div className="x_title sub_title">
<h2>Recent Activites</h2>
</div>
<div className="x_content">
<div className="dashboard-widget-content">
<ul className="list-unstyled timeline widget">
<InfiniteLoader
isRowLoaded={this._isRowLoaded}
loadMoreRows={this._loadMoreRows}
rowCount={list.length}>
{({onRowsRendered, registerChild}) => (
<div className={styles.list}>
<AutoSizer onResize={this.updateDimensions.bind(this)}>
{({width, height}) => (
<List
ref={(ref) => {
this.activitiList = ref;
registerChild(ref);
}}
noRowsRenderer={this.noRowsRenderer}
onRowsRendered={this.onRowsRendered}
deferredMeasurementCache={this.cache}
width={width}
height={height}
deferredMeasurementCache={this.cache}
rowHeight={this.cache.rowHeight}
rowRenderer={this.renderRow}
rowCount={list.length} /* Initially render 20 records */
/>
)}
</AutoSizer>
</div>
)}
</InfiniteLoader>
</ul>
{/* <div className="align-right">
<a href="http://karthik.jivox.com/studio/eam/production/index.php#"
className="btn-jivox-1">
<span className="btn-icon">
<i className="fas fa-chevron-down" aria-hidden="true"></i>
</span> Show More Activities
</a>
</div> */}
</div>
</div>
</div>
</div>
);
}
}
const RecentActiviti = connect(mapStateToProps, mapDispatchToProps)(RecentActivitiComp);
export default RecentActiviti;
As you can see I am making API call at didMount phase and therefore populating my redux store with the data. Data is coming fine. But isRowLoaded and loadMoreRows are not getting called.
I have debugged the sample code of infiniteLoader.example.js, there during the inital render those two functions are called and properly set loadedRowsMap.
What I am doing wrong here ? :-( Any help would be greatly appreciated .
react-virtualized
add a comment |
My _loadMoreRows and _isRowLoaded are not getting called, so loadedRowsMap remains empty and I am unable to identify the rows loaded to avoid making HTTP request .
Here's my complete code :
import React, { Component } from 'react';
import { connect } from 'react-redux';
import {formatDate} from '../../helper/date';
import { recentActivitiAction } from '../actions/dashboardAction';
import { BeatLoader } from 'react-spinners';
import {AutoSizer, List, CellMeasurer, InfiniteLoader, CellMeasurerCache} from 'react-virtualized';
import styles from '../../css/AutoSizer.module.css';
import Skeleton from 'react-skeleton-loader';
const STATUS_LOADING = 1;
const STATUS_LOADED = 2;
const mapStateToProps = (state) => {
return {
recentActList: state.dashboardReducer.recentActList,
activitiLoading: state.dashboardReducer.activitiLoading
}
}
const mapDispatchToProps = (dispatch) => {
return {
getRecentActivites: (postData, callback) => {
dispatch(recentActivitiAction(postData, callback));
}
};
}
class RecentActivitiComp extends Component {
constructor(props) {
super(props);
this.state = {
loadedRowCount: 0,
loadedRowsMap: {},
loadingRowCount: 0,
};
this.cache = new CellMeasurerCache({
fixedWidth: true,
defaultHeight: 100
});
this._timeoutIdMap = {};
this._isRowLoaded = this._isRowLoaded.bind(this);
this._loadMoreRows = this._loadMoreRows.bind(this);
this.renderRow = this.renderRow.bind(this);
this.onRowsRendered = this.onRowsRendered.bind(this);
this.noRowsRenderer = this.noRowsRenderer.bind(this);
}
componentWillUnmount() {
Object.keys(this._timeoutIdMap).forEach(timeoutId => {
clearTimeout(timeoutId);
});
}
componentDidMount() {
var postData = {
"userName": "admin",
"queryType": "GET_RECENT_PROJECTS",
"data": {
pageStart: 1,
pageEnd: 20
}
};
this.props.getRecentActivites(postData, this.recentActResponse.bind(this));
}
updateDimensions() {
this.cache.clearAll();
this.activitiList.recomputeRowHeights();
}
recentActResponse(response) {
if (response.status === "FAILED") {
// handle error
}
}
_fieldGenerator(row, index) {
var formattedDate = formatDate(row.lastModified),
output = '', JSX = '';
if(formattedDate) {
formattedDate = formattedDate.split('-');
output = (
<div className="project-info-value byline">
<span>{formattedDate[0]}<sup>{formattedDate[1]}</sup> {formattedDate[2]} {formattedDate[3]}</span> by <a>{row.modifiedBy}</a>
</div>
)
} else {
output = (
<div className="project-info-value byline">
<span>Invalid Date by </span> <a>{row.modifiedBy}</a>
</div>
)
}
if(row.action === "upcoming-release") {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title">{row.action}</h2>
{output}
<p className="excerpt">{row.notes}<a> Read More</a></p>
</div>
</div>
</li>
} else if(row.action === "created") {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title">{row.type} <a>{row.name}</a> {row.action}</h2>
{output}
<p className="excerpt"></p>
</div>
</div>
</li>
} else if(row.action === "modified") {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title">{row.type} <a>{row.name}</a> {row.action}</h2>
{output}
<p className="excerpt"></p>
</div>
</div>
</li>
} else {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title"><a>{row.person}</a> added to <a>{row.addedTo}</a></h2>
{output}
<p className="excerpt"></p>
</div>
</div>
</li>
}
return JSX;
}
renderRow({ index, key, style, parent }) {
var JSX = '', content = '';
const list = this.props.recentActList
const {loadedRowsMap} = this.state;
if (loadedRowsMap[index] === STATUS_LOADED) {
const row = list[index];
JSX = this._fieldGenerator(row, index);
content = (
JSX
);
} else {
content = (
<div className={styles.placeholder} style={{width: 480}} />
);
}
return (
<CellMeasurer
cache={this.cache}
columnIndex={0}
key={key}
parent={parent}
rowIndex={index}
>
{({ measure }) => (
<div key={key} style={{...style}} onLoad={measure}>
{content}
</div>
)}
</CellMeasurer>
);
}
_isRowLoaded({index}) {
const {loadedRowsMap} = this.state;
return !!loadedRowsMap[index]; // STATUS_LOADING or STATUS_LOADED
}
_loadMoreRows({startIndex, stopIndex}) {
const {loadedRowsMap, loadingRowCount} = this.state;
const increment = stopIndex - startIndex + 1;
for (var i = startIndex; i <= stopIndex; i++) {
loadedRowsMap[i] = STATUS_LOADING;
}
this.setState({
loadingRowCount: loadingRowCount + increment,
});
const timeoutId = setTimeout(() => {
const {loadedRowCount, loadingRowCount} = this.state;
delete this._timeoutIdMap[timeoutId];
for (var i = startIndex; i <= stopIndex; i++) {
loadedRowsMap[i] = STATUS_LOADED;
}
this.setState({
loadingRowCount: loadingRowCount - increment,
loadedRowCount: loadedRowCount + increment,
});
promiseResolver();
}, 1000 + Math.round(Math.random() * 2000));
this._timeoutIdMap[timeoutId] = true;
let promiseResolver;
return new Promise(resolve => {
promiseResolver = resolve;
});
}
noRowsRenderer() {
return <div className={styles.noRows}>No rows</div>;
}
onRowsRendered({overscanStartIndex, overscanStopIndex, startIndex, stopIndex}) {
const list = this.props.recentActList.length ? this.props.recentActList : ;
const {loadedRowsMap} = this.state;
console.log(startIndex, stopIndex, this.state.loadedRowCount);
// if(startIndex + 10 === list.length && this._isRowLoaded(startIndex) !== STATUS_LOADED) {
// var postData = {
// "userName": "admin",
// "queryType": "GET_RECENT_PROJECTS",
// "data": {
// pageStart: 1,
// pageEnd: 10
// }
// };
// this.props.getRecentActivites(postData, this.recentActResponse.bind(this));
// }
}
render() {
const list = this.props.recentActList.length ? this.props.recentActList : ;
const {loadedRowCount, loadingRowCount} = this.state;
return (
<div className="recent left_panel">
<div className="x_panel">
<div className="x_title sub_title">
<h2>Recent Activites</h2>
</div>
<div className="x_content">
<div className="dashboard-widget-content">
<ul className="list-unstyled timeline widget">
<InfiniteLoader
isRowLoaded={this._isRowLoaded}
loadMoreRows={this._loadMoreRows}
rowCount={list.length}>
{({onRowsRendered, registerChild}) => (
<div className={styles.list}>
<AutoSizer onResize={this.updateDimensions.bind(this)}>
{({width, height}) => (
<List
ref={(ref) => {
this.activitiList = ref;
registerChild(ref);
}}
noRowsRenderer={this.noRowsRenderer}
onRowsRendered={this.onRowsRendered}
deferredMeasurementCache={this.cache}
width={width}
height={height}
deferredMeasurementCache={this.cache}
rowHeight={this.cache.rowHeight}
rowRenderer={this.renderRow}
rowCount={list.length} /* Initially render 20 records */
/>
)}
</AutoSizer>
</div>
)}
</InfiniteLoader>
</ul>
{/* <div className="align-right">
<a href="http://karthik.jivox.com/studio/eam/production/index.php#"
className="btn-jivox-1">
<span className="btn-icon">
<i className="fas fa-chevron-down" aria-hidden="true"></i>
</span> Show More Activities
</a>
</div> */}
</div>
</div>
</div>
</div>
);
}
}
const RecentActiviti = connect(mapStateToProps, mapDispatchToProps)(RecentActivitiComp);
export default RecentActiviti;
As you can see I am making API call at didMount phase and therefore populating my redux store with the data. Data is coming fine. But isRowLoaded and loadMoreRows are not getting called.
I have debugged the sample code of infiniteLoader.example.js, there during the inital render those two functions are called and properly set loadedRowsMap.
What I am doing wrong here ? :-( Any help would be greatly appreciated .
react-virtualized
@bvaughn sorry to bother you. If you have time can you please take a look ?
– Arjita Mitra
Nov 23 '18 at 11:57
add a comment |
My _loadMoreRows and _isRowLoaded are not getting called, so loadedRowsMap remains empty and I am unable to identify the rows loaded to avoid making HTTP request .
Here's my complete code :
import React, { Component } from 'react';
import { connect } from 'react-redux';
import {formatDate} from '../../helper/date';
import { recentActivitiAction } from '../actions/dashboardAction';
import { BeatLoader } from 'react-spinners';
import {AutoSizer, List, CellMeasurer, InfiniteLoader, CellMeasurerCache} from 'react-virtualized';
import styles from '../../css/AutoSizer.module.css';
import Skeleton from 'react-skeleton-loader';
const STATUS_LOADING = 1;
const STATUS_LOADED = 2;
const mapStateToProps = (state) => {
return {
recentActList: state.dashboardReducer.recentActList,
activitiLoading: state.dashboardReducer.activitiLoading
}
}
const mapDispatchToProps = (dispatch) => {
return {
getRecentActivites: (postData, callback) => {
dispatch(recentActivitiAction(postData, callback));
}
};
}
class RecentActivitiComp extends Component {
constructor(props) {
super(props);
this.state = {
loadedRowCount: 0,
loadedRowsMap: {},
loadingRowCount: 0,
};
this.cache = new CellMeasurerCache({
fixedWidth: true,
defaultHeight: 100
});
this._timeoutIdMap = {};
this._isRowLoaded = this._isRowLoaded.bind(this);
this._loadMoreRows = this._loadMoreRows.bind(this);
this.renderRow = this.renderRow.bind(this);
this.onRowsRendered = this.onRowsRendered.bind(this);
this.noRowsRenderer = this.noRowsRenderer.bind(this);
}
componentWillUnmount() {
Object.keys(this._timeoutIdMap).forEach(timeoutId => {
clearTimeout(timeoutId);
});
}
componentDidMount() {
var postData = {
"userName": "admin",
"queryType": "GET_RECENT_PROJECTS",
"data": {
pageStart: 1,
pageEnd: 20
}
};
this.props.getRecentActivites(postData, this.recentActResponse.bind(this));
}
updateDimensions() {
this.cache.clearAll();
this.activitiList.recomputeRowHeights();
}
recentActResponse(response) {
if (response.status === "FAILED") {
// handle error
}
}
_fieldGenerator(row, index) {
var formattedDate = formatDate(row.lastModified),
output = '', JSX = '';
if(formattedDate) {
formattedDate = formattedDate.split('-');
output = (
<div className="project-info-value byline">
<span>{formattedDate[0]}<sup>{formattedDate[1]}</sup> {formattedDate[2]} {formattedDate[3]}</span> by <a>{row.modifiedBy}</a>
</div>
)
} else {
output = (
<div className="project-info-value byline">
<span>Invalid Date by </span> <a>{row.modifiedBy}</a>
</div>
)
}
if(row.action === "upcoming-release") {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title">{row.action}</h2>
{output}
<p className="excerpt">{row.notes}<a> Read More</a></p>
</div>
</div>
</li>
} else if(row.action === "created") {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title">{row.type} <a>{row.name}</a> {row.action}</h2>
{output}
<p className="excerpt"></p>
</div>
</div>
</li>
} else if(row.action === "modified") {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title">{row.type} <a>{row.name}</a> {row.action}</h2>
{output}
<p className="excerpt"></p>
</div>
</div>
</li>
} else {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title"><a>{row.person}</a> added to <a>{row.addedTo}</a></h2>
{output}
<p className="excerpt"></p>
</div>
</div>
</li>
}
return JSX;
}
renderRow({ index, key, style, parent }) {
var JSX = '', content = '';
const list = this.props.recentActList
const {loadedRowsMap} = this.state;
if (loadedRowsMap[index] === STATUS_LOADED) {
const row = list[index];
JSX = this._fieldGenerator(row, index);
content = (
JSX
);
} else {
content = (
<div className={styles.placeholder} style={{width: 480}} />
);
}
return (
<CellMeasurer
cache={this.cache}
columnIndex={0}
key={key}
parent={parent}
rowIndex={index}
>
{({ measure }) => (
<div key={key} style={{...style}} onLoad={measure}>
{content}
</div>
)}
</CellMeasurer>
);
}
_isRowLoaded({index}) {
const {loadedRowsMap} = this.state;
return !!loadedRowsMap[index]; // STATUS_LOADING or STATUS_LOADED
}
_loadMoreRows({startIndex, stopIndex}) {
const {loadedRowsMap, loadingRowCount} = this.state;
const increment = stopIndex - startIndex + 1;
for (var i = startIndex; i <= stopIndex; i++) {
loadedRowsMap[i] = STATUS_LOADING;
}
this.setState({
loadingRowCount: loadingRowCount + increment,
});
const timeoutId = setTimeout(() => {
const {loadedRowCount, loadingRowCount} = this.state;
delete this._timeoutIdMap[timeoutId];
for (var i = startIndex; i <= stopIndex; i++) {
loadedRowsMap[i] = STATUS_LOADED;
}
this.setState({
loadingRowCount: loadingRowCount - increment,
loadedRowCount: loadedRowCount + increment,
});
promiseResolver();
}, 1000 + Math.round(Math.random() * 2000));
this._timeoutIdMap[timeoutId] = true;
let promiseResolver;
return new Promise(resolve => {
promiseResolver = resolve;
});
}
noRowsRenderer() {
return <div className={styles.noRows}>No rows</div>;
}
onRowsRendered({overscanStartIndex, overscanStopIndex, startIndex, stopIndex}) {
const list = this.props.recentActList.length ? this.props.recentActList : ;
const {loadedRowsMap} = this.state;
console.log(startIndex, stopIndex, this.state.loadedRowCount);
// if(startIndex + 10 === list.length && this._isRowLoaded(startIndex) !== STATUS_LOADED) {
// var postData = {
// "userName": "admin",
// "queryType": "GET_RECENT_PROJECTS",
// "data": {
// pageStart: 1,
// pageEnd: 10
// }
// };
// this.props.getRecentActivites(postData, this.recentActResponse.bind(this));
// }
}
render() {
const list = this.props.recentActList.length ? this.props.recentActList : ;
const {loadedRowCount, loadingRowCount} = this.state;
return (
<div className="recent left_panel">
<div className="x_panel">
<div className="x_title sub_title">
<h2>Recent Activites</h2>
</div>
<div className="x_content">
<div className="dashboard-widget-content">
<ul className="list-unstyled timeline widget">
<InfiniteLoader
isRowLoaded={this._isRowLoaded}
loadMoreRows={this._loadMoreRows}
rowCount={list.length}>
{({onRowsRendered, registerChild}) => (
<div className={styles.list}>
<AutoSizer onResize={this.updateDimensions.bind(this)}>
{({width, height}) => (
<List
ref={(ref) => {
this.activitiList = ref;
registerChild(ref);
}}
noRowsRenderer={this.noRowsRenderer}
onRowsRendered={this.onRowsRendered}
deferredMeasurementCache={this.cache}
width={width}
height={height}
deferredMeasurementCache={this.cache}
rowHeight={this.cache.rowHeight}
rowRenderer={this.renderRow}
rowCount={list.length} /* Initially render 20 records */
/>
)}
</AutoSizer>
</div>
)}
</InfiniteLoader>
</ul>
{/* <div className="align-right">
<a href="http://karthik.jivox.com/studio/eam/production/index.php#"
className="btn-jivox-1">
<span className="btn-icon">
<i className="fas fa-chevron-down" aria-hidden="true"></i>
</span> Show More Activities
</a>
</div> */}
</div>
</div>
</div>
</div>
);
}
}
const RecentActiviti = connect(mapStateToProps, mapDispatchToProps)(RecentActivitiComp);
export default RecentActiviti;
As you can see I am making API call at didMount phase and therefore populating my redux store with the data. Data is coming fine. But isRowLoaded and loadMoreRows are not getting called.
I have debugged the sample code of infiniteLoader.example.js, there during the inital render those two functions are called and properly set loadedRowsMap.
What I am doing wrong here ? :-( Any help would be greatly appreciated .
react-virtualized
My _loadMoreRows and _isRowLoaded are not getting called, so loadedRowsMap remains empty and I am unable to identify the rows loaded to avoid making HTTP request .
Here's my complete code :
import React, { Component } from 'react';
import { connect } from 'react-redux';
import {formatDate} from '../../helper/date';
import { recentActivitiAction } from '../actions/dashboardAction';
import { BeatLoader } from 'react-spinners';
import {AutoSizer, List, CellMeasurer, InfiniteLoader, CellMeasurerCache} from 'react-virtualized';
import styles from '../../css/AutoSizer.module.css';
import Skeleton from 'react-skeleton-loader';
const STATUS_LOADING = 1;
const STATUS_LOADED = 2;
const mapStateToProps = (state) => {
return {
recentActList: state.dashboardReducer.recentActList,
activitiLoading: state.dashboardReducer.activitiLoading
}
}
const mapDispatchToProps = (dispatch) => {
return {
getRecentActivites: (postData, callback) => {
dispatch(recentActivitiAction(postData, callback));
}
};
}
class RecentActivitiComp extends Component {
constructor(props) {
super(props);
this.state = {
loadedRowCount: 0,
loadedRowsMap: {},
loadingRowCount: 0,
};
this.cache = new CellMeasurerCache({
fixedWidth: true,
defaultHeight: 100
});
this._timeoutIdMap = {};
this._isRowLoaded = this._isRowLoaded.bind(this);
this._loadMoreRows = this._loadMoreRows.bind(this);
this.renderRow = this.renderRow.bind(this);
this.onRowsRendered = this.onRowsRendered.bind(this);
this.noRowsRenderer = this.noRowsRenderer.bind(this);
}
componentWillUnmount() {
Object.keys(this._timeoutIdMap).forEach(timeoutId => {
clearTimeout(timeoutId);
});
}
componentDidMount() {
var postData = {
"userName": "admin",
"queryType": "GET_RECENT_PROJECTS",
"data": {
pageStart: 1,
pageEnd: 20
}
};
this.props.getRecentActivites(postData, this.recentActResponse.bind(this));
}
updateDimensions() {
this.cache.clearAll();
this.activitiList.recomputeRowHeights();
}
recentActResponse(response) {
if (response.status === "FAILED") {
// handle error
}
}
_fieldGenerator(row, index) {
var formattedDate = formatDate(row.lastModified),
output = '', JSX = '';
if(formattedDate) {
formattedDate = formattedDate.split('-');
output = (
<div className="project-info-value byline">
<span>{formattedDate[0]}<sup>{formattedDate[1]}</sup> {formattedDate[2]} {formattedDate[3]}</span> by <a>{row.modifiedBy}</a>
</div>
)
} else {
output = (
<div className="project-info-value byline">
<span>Invalid Date by </span> <a>{row.modifiedBy}</a>
</div>
)
}
if(row.action === "upcoming-release") {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title">{row.action}</h2>
{output}
<p className="excerpt">{row.notes}<a> Read More</a></p>
</div>
</div>
</li>
} else if(row.action === "created") {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title">{row.type} <a>{row.name}</a> {row.action}</h2>
{output}
<p className="excerpt"></p>
</div>
</div>
</li>
} else if(row.action === "modified") {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title">{row.type} <a>{row.name}</a> {row.action}</h2>
{output}
<p className="excerpt"></p>
</div>
</div>
</li>
} else {
JSX =
<li key={index}>
<div className="block">
<div className="block_content">
<h2 className="title"><a>{row.person}</a> added to <a>{row.addedTo}</a></h2>
{output}
<p className="excerpt"></p>
</div>
</div>
</li>
}
return JSX;
}
renderRow({ index, key, style, parent }) {
var JSX = '', content = '';
const list = this.props.recentActList
const {loadedRowsMap} = this.state;
if (loadedRowsMap[index] === STATUS_LOADED) {
const row = list[index];
JSX = this._fieldGenerator(row, index);
content = (
JSX
);
} else {
content = (
<div className={styles.placeholder} style={{width: 480}} />
);
}
return (
<CellMeasurer
cache={this.cache}
columnIndex={0}
key={key}
parent={parent}
rowIndex={index}
>
{({ measure }) => (
<div key={key} style={{...style}} onLoad={measure}>
{content}
</div>
)}
</CellMeasurer>
);
}
_isRowLoaded({index}) {
const {loadedRowsMap} = this.state;
return !!loadedRowsMap[index]; // STATUS_LOADING or STATUS_LOADED
}
_loadMoreRows({startIndex, stopIndex}) {
const {loadedRowsMap, loadingRowCount} = this.state;
const increment = stopIndex - startIndex + 1;
for (var i = startIndex; i <= stopIndex; i++) {
loadedRowsMap[i] = STATUS_LOADING;
}
this.setState({
loadingRowCount: loadingRowCount + increment,
});
const timeoutId = setTimeout(() => {
const {loadedRowCount, loadingRowCount} = this.state;
delete this._timeoutIdMap[timeoutId];
for (var i = startIndex; i <= stopIndex; i++) {
loadedRowsMap[i] = STATUS_LOADED;
}
this.setState({
loadingRowCount: loadingRowCount - increment,
loadedRowCount: loadedRowCount + increment,
});
promiseResolver();
}, 1000 + Math.round(Math.random() * 2000));
this._timeoutIdMap[timeoutId] = true;
let promiseResolver;
return new Promise(resolve => {
promiseResolver = resolve;
});
}
noRowsRenderer() {
return <div className={styles.noRows}>No rows</div>;
}
onRowsRendered({overscanStartIndex, overscanStopIndex, startIndex, stopIndex}) {
const list = this.props.recentActList.length ? this.props.recentActList : ;
const {loadedRowsMap} = this.state;
console.log(startIndex, stopIndex, this.state.loadedRowCount);
// if(startIndex + 10 === list.length && this._isRowLoaded(startIndex) !== STATUS_LOADED) {
// var postData = {
// "userName": "admin",
// "queryType": "GET_RECENT_PROJECTS",
// "data": {
// pageStart: 1,
// pageEnd: 10
// }
// };
// this.props.getRecentActivites(postData, this.recentActResponse.bind(this));
// }
}
render() {
const list = this.props.recentActList.length ? this.props.recentActList : ;
const {loadedRowCount, loadingRowCount} = this.state;
return (
<div className="recent left_panel">
<div className="x_panel">
<div className="x_title sub_title">
<h2>Recent Activites</h2>
</div>
<div className="x_content">
<div className="dashboard-widget-content">
<ul className="list-unstyled timeline widget">
<InfiniteLoader
isRowLoaded={this._isRowLoaded}
loadMoreRows={this._loadMoreRows}
rowCount={list.length}>
{({onRowsRendered, registerChild}) => (
<div className={styles.list}>
<AutoSizer onResize={this.updateDimensions.bind(this)}>
{({width, height}) => (
<List
ref={(ref) => {
this.activitiList = ref;
registerChild(ref);
}}
noRowsRenderer={this.noRowsRenderer}
onRowsRendered={this.onRowsRendered}
deferredMeasurementCache={this.cache}
width={width}
height={height}
deferredMeasurementCache={this.cache}
rowHeight={this.cache.rowHeight}
rowRenderer={this.renderRow}
rowCount={list.length} /* Initially render 20 records */
/>
)}
</AutoSizer>
</div>
)}
</InfiniteLoader>
</ul>
{/* <div className="align-right">
<a href="http://karthik.jivox.com/studio/eam/production/index.php#"
className="btn-jivox-1">
<span className="btn-icon">
<i className="fas fa-chevron-down" aria-hidden="true"></i>
</span> Show More Activities
</a>
</div> */}
</div>
</div>
</div>
</div>
);
}
}
const RecentActiviti = connect(mapStateToProps, mapDispatchToProps)(RecentActivitiComp);
export default RecentActiviti;
As you can see I am making API call at didMount phase and therefore populating my redux store with the data. Data is coming fine. But isRowLoaded and loadMoreRows are not getting called.
I have debugged the sample code of infiniteLoader.example.js, there during the inital render those two functions are called and properly set loadedRowsMap.
What I am doing wrong here ? :-( Any help would be greatly appreciated .
react-virtualized
react-virtualized
edited Dec 8 '18 at 13:52
Arjita Mitra
asked Nov 23 '18 at 11:56
Arjita MitraArjita Mitra
4541723
4541723
@bvaughn sorry to bother you. If you have time can you please take a look ?
– Arjita Mitra
Nov 23 '18 at 11:57
add a comment |
@bvaughn sorry to bother you. If you have time can you please take a look ?
– Arjita Mitra
Nov 23 '18 at 11:57
@bvaughn sorry to bother you. If you have time can you please take a look ?
– Arjita Mitra
Nov 23 '18 at 11:57
@bvaughn sorry to bother you. If you have time can you please take a look ?
– Arjita Mitra
Nov 23 '18 at 11:57
add a comment |
2 Answers
2
active
oldest
votes
(The code you've posted has a lot going on; you'll probably get better responses if you remove the parts that aren't related to your question.)
My advice is to take a look at the values you're getting for list.length
, which you're passing to InfiniteLoader's rowCount
prop. InfiniteLoader will only call loadMoreRows
if rowCount
is higher than the number of rows it has data for.
For example: during the first render, the value is 0, because you have not fetched any data yet. This prevents a call to loadMoreRows
during the first render.
I also noticed that you are keeping loadedRowCount
and loadingRowCount
in state, but you never use them for anything. I don't think that's related to your issue, but it's also probably not intentional.
add a comment |
I have resolved the issue after making some changes.
const mapStateToProps = (state) => {
return {
myList: state.dashboardReducer.myList
}
}
const list = this.props.myList.length ? this.props.recentActList : ;
const rowCount = list.length + (moreToBeLoaded ? 1 : 0);
To know why 1 more row loaded pls check this post react-virtualized InfiniteLoader/List - working example using AJAX
So the issue in my code was I was writing my custom onRowsRendered function and it was not handling the response correctly. Now I changed the code to use the one passed by InfiniteLoader.
Hope that helps.
<InfiniteLoader
isRowLoaded={this._isRowLoaded}
loadMoreRows={this._loadMoreRows}
rowCount={rowCount}>
{({onRowsRendered, registerChild}) => (
<div className={styles.list}>
<AutoSizer onResize={this.updateDimensions.bind(this)}>
{({width, height}) => (
<ActiviitiList
ref={(ref) => {
this.activitiList = ref;
registerChild(ref);
}}
width={width}
height={height}
onRowsRendered={onRowsRendered}
rowCount={rowCount}
rowHeight={this.cache.rowHeight}
rowRenderer={this._rowRenderer}
overscanRowCount={3}
deferredMeasurementCache={this.cache}
/>
)}
</AutoSizer>
</div>
)}
</InfiniteLoader>
add a comment |
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53446274%2fisrowloaded-and-loadmorerows-not-getting-called-react-virtualized%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
(The code you've posted has a lot going on; you'll probably get better responses if you remove the parts that aren't related to your question.)
My advice is to take a look at the values you're getting for list.length
, which you're passing to InfiniteLoader's rowCount
prop. InfiniteLoader will only call loadMoreRows
if rowCount
is higher than the number of rows it has data for.
For example: during the first render, the value is 0, because you have not fetched any data yet. This prevents a call to loadMoreRows
during the first render.
I also noticed that you are keeping loadedRowCount
and loadingRowCount
in state, but you never use them for anything. I don't think that's related to your issue, but it's also probably not intentional.
add a comment |
(The code you've posted has a lot going on; you'll probably get better responses if you remove the parts that aren't related to your question.)
My advice is to take a look at the values you're getting for list.length
, which you're passing to InfiniteLoader's rowCount
prop. InfiniteLoader will only call loadMoreRows
if rowCount
is higher than the number of rows it has data for.
For example: during the first render, the value is 0, because you have not fetched any data yet. This prevents a call to loadMoreRows
during the first render.
I also noticed that you are keeping loadedRowCount
and loadingRowCount
in state, but you never use them for anything. I don't think that's related to your issue, but it's also probably not intentional.
add a comment |
(The code you've posted has a lot going on; you'll probably get better responses if you remove the parts that aren't related to your question.)
My advice is to take a look at the values you're getting for list.length
, which you're passing to InfiniteLoader's rowCount
prop. InfiniteLoader will only call loadMoreRows
if rowCount
is higher than the number of rows it has data for.
For example: during the first render, the value is 0, because you have not fetched any data yet. This prevents a call to loadMoreRows
during the first render.
I also noticed that you are keeping loadedRowCount
and loadingRowCount
in state, but you never use them for anything. I don't think that's related to your issue, but it's also probably not intentional.
(The code you've posted has a lot going on; you'll probably get better responses if you remove the parts that aren't related to your question.)
My advice is to take a look at the values you're getting for list.length
, which you're passing to InfiniteLoader's rowCount
prop. InfiniteLoader will only call loadMoreRows
if rowCount
is higher than the number of rows it has data for.
For example: during the first render, the value is 0, because you have not fetched any data yet. This prevents a call to loadMoreRows
during the first render.
I also noticed that you are keeping loadedRowCount
and loadingRowCount
in state, but you never use them for anything. I don't think that's related to your issue, but it's also probably not intentional.
answered Dec 6 '18 at 15:01
Eric the RedEric the Red
5381613
5381613
add a comment |
add a comment |
I have resolved the issue after making some changes.
const mapStateToProps = (state) => {
return {
myList: state.dashboardReducer.myList
}
}
const list = this.props.myList.length ? this.props.recentActList : ;
const rowCount = list.length + (moreToBeLoaded ? 1 : 0);
To know why 1 more row loaded pls check this post react-virtualized InfiniteLoader/List - working example using AJAX
So the issue in my code was I was writing my custom onRowsRendered function and it was not handling the response correctly. Now I changed the code to use the one passed by InfiniteLoader.
Hope that helps.
<InfiniteLoader
isRowLoaded={this._isRowLoaded}
loadMoreRows={this._loadMoreRows}
rowCount={rowCount}>
{({onRowsRendered, registerChild}) => (
<div className={styles.list}>
<AutoSizer onResize={this.updateDimensions.bind(this)}>
{({width, height}) => (
<ActiviitiList
ref={(ref) => {
this.activitiList = ref;
registerChild(ref);
}}
width={width}
height={height}
onRowsRendered={onRowsRendered}
rowCount={rowCount}
rowHeight={this.cache.rowHeight}
rowRenderer={this._rowRenderer}
overscanRowCount={3}
deferredMeasurementCache={this.cache}
/>
)}
</AutoSizer>
</div>
)}
</InfiniteLoader>
add a comment |
I have resolved the issue after making some changes.
const mapStateToProps = (state) => {
return {
myList: state.dashboardReducer.myList
}
}
const list = this.props.myList.length ? this.props.recentActList : ;
const rowCount = list.length + (moreToBeLoaded ? 1 : 0);
To know why 1 more row loaded pls check this post react-virtualized InfiniteLoader/List - working example using AJAX
So the issue in my code was I was writing my custom onRowsRendered function and it was not handling the response correctly. Now I changed the code to use the one passed by InfiniteLoader.
Hope that helps.
<InfiniteLoader
isRowLoaded={this._isRowLoaded}
loadMoreRows={this._loadMoreRows}
rowCount={rowCount}>
{({onRowsRendered, registerChild}) => (
<div className={styles.list}>
<AutoSizer onResize={this.updateDimensions.bind(this)}>
{({width, height}) => (
<ActiviitiList
ref={(ref) => {
this.activitiList = ref;
registerChild(ref);
}}
width={width}
height={height}
onRowsRendered={onRowsRendered}
rowCount={rowCount}
rowHeight={this.cache.rowHeight}
rowRenderer={this._rowRenderer}
overscanRowCount={3}
deferredMeasurementCache={this.cache}
/>
)}
</AutoSizer>
</div>
)}
</InfiniteLoader>
add a comment |
I have resolved the issue after making some changes.
const mapStateToProps = (state) => {
return {
myList: state.dashboardReducer.myList
}
}
const list = this.props.myList.length ? this.props.recentActList : ;
const rowCount = list.length + (moreToBeLoaded ? 1 : 0);
To know why 1 more row loaded pls check this post react-virtualized InfiniteLoader/List - working example using AJAX
So the issue in my code was I was writing my custom onRowsRendered function and it was not handling the response correctly. Now I changed the code to use the one passed by InfiniteLoader.
Hope that helps.
<InfiniteLoader
isRowLoaded={this._isRowLoaded}
loadMoreRows={this._loadMoreRows}
rowCount={rowCount}>
{({onRowsRendered, registerChild}) => (
<div className={styles.list}>
<AutoSizer onResize={this.updateDimensions.bind(this)}>
{({width, height}) => (
<ActiviitiList
ref={(ref) => {
this.activitiList = ref;
registerChild(ref);
}}
width={width}
height={height}
onRowsRendered={onRowsRendered}
rowCount={rowCount}
rowHeight={this.cache.rowHeight}
rowRenderer={this._rowRenderer}
overscanRowCount={3}
deferredMeasurementCache={this.cache}
/>
)}
</AutoSizer>
</div>
)}
</InfiniteLoader>
I have resolved the issue after making some changes.
const mapStateToProps = (state) => {
return {
myList: state.dashboardReducer.myList
}
}
const list = this.props.myList.length ? this.props.recentActList : ;
const rowCount = list.length + (moreToBeLoaded ? 1 : 0);
To know why 1 more row loaded pls check this post react-virtualized InfiniteLoader/List - working example using AJAX
So the issue in my code was I was writing my custom onRowsRendered function and it was not handling the response correctly. Now I changed the code to use the one passed by InfiniteLoader.
Hope that helps.
<InfiniteLoader
isRowLoaded={this._isRowLoaded}
loadMoreRows={this._loadMoreRows}
rowCount={rowCount}>
{({onRowsRendered, registerChild}) => (
<div className={styles.list}>
<AutoSizer onResize={this.updateDimensions.bind(this)}>
{({width, height}) => (
<ActiviitiList
ref={(ref) => {
this.activitiList = ref;
registerChild(ref);
}}
width={width}
height={height}
onRowsRendered={onRowsRendered}
rowCount={rowCount}
rowHeight={this.cache.rowHeight}
rowRenderer={this._rowRenderer}
overscanRowCount={3}
deferredMeasurementCache={this.cache}
/>
)}
</AutoSizer>
</div>
)}
</InfiniteLoader>
answered Dec 8 '18 at 14:14
Arjita MitraArjita Mitra
4541723
4541723
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53446274%2fisrowloaded-and-loadmorerows-not-getting-called-react-virtualized%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
@bvaughn sorry to bother you. If you have time can you please take a look ?
– Arjita Mitra
Nov 23 '18 at 11:57