UNPKG

react-composable-list

Version:
104 lines (89 loc) 2.81 kB
import React from 'react/addons'; class ListInner extends React.Component { _renderChildren() { let children = this.props.items; let scrollTop = this.props.scrollTop; let outerHeight = this.props.height; let topHiddenHeight = 0, bottomHiddenHeight = 0, visibleHeight = 0, firstRenderIndex = -1, lastRenderIndex = Infinity; let realChildren = []; for (let i = 0; i < children.length; i++) { let childHeight = children[i].props.height; if (visibleHeight >= outerHeight) { if (lastRenderIndex === Infinity) { lastRenderIndex = i - 1; } bottomHiddenHeight += childHeight; } else if (topHiddenHeight + childHeight > scrollTop) { if (firstRenderIndex === -1) { firstRenderIndex = i; visibleHeight += topHiddenHeight - scrollTop; } realChildren.push(children[i]); visibleHeight += childHeight; } else { topHiddenHeight += childHeight; } } if (visibleHeight < outerHeight) { for (let i = firstRenderIndex - 1; i >= 0; i--) { if (visibleHeight < outerHeight) { realChildren.unshift(children[i]); let height = children[i].props.height; visibleHeight += height; topHiddenHeight -= height; firstRenderIndex -= 1; } else { break; } } } // 前后 预先渲染好 各20个 let prepareNodeCount = 20; for (let i = firstRenderIndex - 1; i >= 0 && i >= firstRenderIndex - prepareNodeCount; i--) { realChildren.unshift(children[i]); let height = children[i].props.height; visibleHeight += height; topHiddenHeight -= height; } for (let i = lastRenderIndex + 1; i < children.length && i <= lastRenderIndex + prepareNodeCount; i++) { realChildren.push(children[i]); let height = children[i].props.height; visibleHeight += height; bottomHiddenHeight -= height; } realChildren.push(<div key="bottom_H" style={{height: `${bottomHiddenHeight}px`}}></div>); realChildren.unshift(<div key="top_H" style={{height: `${topHiddenHeight}px`}}></div>); return realChildren; } render() { return ( <div className="mzl-list-container"> { this._renderChildren() } </div> ); } } ListInner.propTypes = { width: React.PropTypes.number.isRequired, height: React.PropTypes.number.isRequired, scrollTop: React.PropTypes.number.isRequired, items: React.PropTypes.array.isRequired }; ListInner.defaultProps = { scrollTop: 0, items: [] }; ListInner.prototype.shouldComponentUpdate = React.addons.PureRenderMixin.shouldComponentUpdate; export default ListInner;