Skip to content

Instantly share code, notes, and snippets.

@DimitryDushkin
Created November 11, 2016 19:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DimitryDushkin/414f40e3fdd12288ca4ff4e6e2e57620 to your computer and use it in GitHub Desktop.
Save DimitryDushkin/414f40e3fdd12288ca4ff4e6e2e57620 to your computer and use it in GitHub Desktop.
Refactored and optimized https://github.com/Radivarig/react-infinite-any-height (I'll do PR!)
import React, { Component, PropTypes} from 'react';
import ReactInfinite from 'react-infinite';
// @copy-paste https://github.com/Radivarig/react-infinite-any-height
// refactored and optimized
/**
* How it works: long story short it adds elements' height on rendering in react-infinite
*/
class InfiniteAnyHeight extends Component {
constructor(props) {
super(props);
this.lastScrollTop = 0;
this.scrollTopDelta = 0;
this.state = {
heights: [],
list: [],
};
this.handleScroll = this.handleScroll.bind(this);
}
getScrollContainer() {
if (this.props.useWindowAsScrollContainer) {
return document.body;
}
return this.props.scrollContainer;
}
addHeight(i, height) {
var heights = this.state.heights,
scrollDiff = height - heights[i];
if (scrollDiff && this.scrollTopDelta < 0) {
this.getScrollContainer().scrollTop += scrollDiff;
}
heights[i] = height;
this.setState({ heights });
}
componentDidMount() {
this.setList(this.props.list);
}
componentWillReceiveProps(nextProps) {
if (nextProps.list != this.props.list) {
this.setList(nextProps.list);
}
}
setList(propsList) {
var heights = [],
list =
propsList.map( (item, i)=>{
heights[i] = this.state.heights[i] || 200;
return (
<GetHeightWrapper
addHeight={ (height) => this.addHeight(i, height) }
key={ i }>
{ item }
</GetHeightWrapper>
);
});
this.setState({
heights,
list,
});
}
handleScroll() {
var scrollTop = this.getScrollContainer().scrollTop;
this.scrollTopDelta = scrollTop - this.lastScrollTop;
this.lastScrollTop = scrollTop;
}
render() {
return (
<ReactInfinite
elementHeight={ this.state.heights }
handleScroll={ this.handleScroll }
{...this.props}>
{this.state.list}
</ReactInfinite>
);
}
}
InfiniteAnyHeight.propTypes = {
useWindowAsScrollContainer: PropTypes.any,
scrollContainer: PropTypes.any,
list: PropTypes.any,
addHeight: PropTypes.any,
children: PropTypes.any
};
class GetHeightWrapper extends Component {
componentDidMount() {
this.props.addHeight(this._el.getBoundingClientRect().height);
}
render() {
return <div ref={ el => this._el = el }>
{ this.props.children }
</div>;
}
}
GetHeightWrapper.propTypes = {
addHeight: PropTypes.func.isRequired,
children: PropTypes.any.isRequired
};
module.exports = InfiniteAnyHeight;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment