Reputation: 207
Im trying to implement infinite scroll for React.js. Everything works fine, except I want to be able to use the window scrollbar, to activate the infinite scroll. The code at the moment, has 2 scrollbars( I only want one).
The code is from stackoverflow answered here, I read his complete answer, I tried setting the height to 100%, but it makes the infinite scroll not work. : Stackoverflow- answered by Aniket Jha, ( the longest answer with 4 upvotes)
Double scroll happens when I render this in this way:
<div>
<First />
<div ref="iScroll" style={{ height: "100vh", overflow: "auto"}}>
<ul>
{this.displayItems()}
</ul>
{this.state.loadingState ? <p className="loading"> loading More
Items..</p> : ""}
</div>
</div>
I have a Link to Codepen if this helps
class Layout extends React.Component {
constructor(props) {
super(props);
this.state = {
items: 30,
loadingState: false
};
}
componentDidMount() {
this.refs.iScroll.addEventListener("scroll", () => {
if (this.refs.iScroll.scrollTop + this.refs.iScroll.clientHeight >= this.refs.iScroll.scrollHeight - 20){
this.loadMoreItems();
}
});
}
displayItems() {
var items = [];
for (var i = 0; i < this.state.items; i++) {
items.push(<li key={i}>Item {i}</li>);
}
return items;
}
loadMoreItems() {
if(this.state.loadingState){
return;
}
this.setState({ loadingState: true });
setTimeout(() => {
this.setState({ items: this.state.items + 10, loadingState: false });
}, 1000);
}
render() {
return (<div>
<First />
<div ref="iScroll" style={{ height: "100vh", overflow: "auto"}}>
<ul>
{this.displayItems()}
</ul>
{this.state.loadingState ? <p className="loading"> loading More Items..</p> : ""}
</div>
</div>
);
}
}
class First extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
return (
<h1>Testing</h1>
)
}
}
ReactDOM.render(<Layout />, document.getElementById('example'));
Upvotes: 7
Views: 10541
Reputation: 808
If you don't want the second scrollbar to appear, you need to style the title and sibling div so that they fit in the available viewport.
In your codepen, you have height: '100%'
for your scrolling div. This styles the div so that it doesn't need to scroll and infinite scroll therefore doesn't work.
If you style that div so that it takes up less than the height of the available viewport, and render enough items to fill it up, infinite scroll will work fine.
If you then style the title div combination so that they fit exactly into the available viewport space, you won't get a second scrollbar.
Below is an option you have to do this. What I've done is set the height of the scrolling div to be the viewport height (100vh
) minus 100px
. That's not precisely calculated, but what you want is to subtract the space required for the title from the size of the viewport.
This implementation works fine for me, and should for you as well.
class Layout extends React.Component {
constructor(props) {
super(props);
this.state = {
items: 30,
loadingState: false
};
}
componentDidMount() {
this.refs.iScroll.addEventListener("scroll", () => {
if (this.refs.iScroll.scrollTop + this.refs.iScroll.clientHeight >= this.refs.iScroll.scrollHeight - 20){
this.loadMoreItems();
}
});
}
displayItems() {
var items = [];
for (var i = 0; i < this.state.items; i++) {
items.push(<li key={i}>Item {i}</li>);
}
return items;
}
loadMoreItems() {
if(this.state.loadingState){
return;
}
this.setState({ loadingState: true });
setTimeout(() => {
this.setState({ items: this.state.items + 10, loadingState: false });
}, 1000);
}
render() {
return (<div>
<First />
<div ref="iScroll" style={{ height: "calc(100vh - 100px)", overflow: "auto"}}>
<ul>
{this.displayItems()}
</ul>
{this.state.loadingState ? <p className="loading"> loading More Items..</p> : ""}
</div>
</div>
);
}
}
class First extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
return (
<h1>Testing</h1>
)
}
}
ReactDOM.render(<Layout />, document.getElementById('example'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="example"></div>
Upvotes: 1