Created
November 11, 2016 19:33
-
-
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!)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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