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 plete 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
};
}
ponentDidMount() {
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'));
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 plete 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
};
}
ponentDidMount() {
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'));
Share
Improve this question
edited May 20, 2018 at 18:50
born2gamble
asked May 20, 2018 at 10:17
born2gambleborn2gamble
2071 gold badge8 silver badges20 bronze badges
2
-
I'm not sure what you mean about "double scrollbars" but I can see that the div is only 200px high. Of course if you set it to 100% then infinite scrolling doesn't work as it's sized too large. I'd suggest trying
height: 100vh
. If I hack it on your codepen, that works well. But then you should also increase the initial number of items — there should be at least 1 more than can fit on the screen. 25 worked for me. – Rajit Commented May 20, 2018 at 17:13 - I updated the codepen. Basically when I am rendering the whole project, the second ponent being this list, it will give me double scrolls <div><First /> <Second/> </div> – born2gamble Commented May 20, 2018 at 18:38
1 Answer
Reset to default 1If 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 bination 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
};
}
ponentDidMount() {
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./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="example"></div>