Skip to content

Commit

Permalink
fix: 🐛 call .laodMore() on multiple short pages
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Sep 23, 2019
1 parent de64a11 commit fe73c91
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 17 deletions.
21 changes: 11 additions & 10 deletions src/InfiniteScroll/__story__/story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@ import ShowDocs from '../../ShowDocs';

const h = React.createElement;

const Block = () => {
const Block = ({height = 100}) => {
return <div style={{
width: 100,
height: 100,
height,
margin: 20,
background: 'red',
}}></div>
};

class Demo extends React.Component {
class Demo extends React.Component<any> {
state = {
items: [
<Block key={0} />,
<Block key={1} />,
<Block key={2} />,
<Block key={3} />,
<Block key={4} />,
<Block key={0} height={this.props.height || 100} />,
<Block key={1} height={this.props.height || 100} />,
<Block key={2} height={this.props.height || 100} />,
<Block key={3} height={this.props.height || 100} />,
<Block key={4} height={this.props.height || 100} />,
],
cursor: 1,
};
Expand All @@ -34,7 +34,7 @@ class Demo extends React.Component {
console.log('loading for cursor: ' + this.state.cursor);
const items = [...this.state.items];
for (let i = 0; i < cnt; i++) {
items.push(<Block key={items.length} />);
items.push(<Block key={items.length} height={this.props.height || 100} />);
}
this.setState({
items,
Expand Down Expand Up @@ -82,7 +82,7 @@ class Demo2 extends React.Component {
render () {
return (
<div style={{border: '1px solid red', height: 400, width: 300, overflowY: 'scroll'}}>
<InfiniteScroll hasMore={this.state.cursor < 5} loadMore={this.load} cursor={this.state.cursor} poll={500}>
<InfiniteScroll hasMore={this.state.cursor < 5} loadMore={this.load} cursor={this.state.cursor} interval={500}>
{this.state.items}
</InfiniteScroll>
</div>
Expand All @@ -93,4 +93,5 @@ class Demo2 extends React.Component {
storiesOf('UI/InfiniteScroll', module)
.add('Documentation', () => h(ShowDocs, {md: require('../../../docs/en/InfiniteScroll.md')}))
.add('Example', () => <Demo />)
.add('Example (short pages)', () => <Demo height={30} />)
.add('Example in <div>', () => <Demo2 />)
47 changes: 40 additions & 7 deletions src/InfiniteScroll/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ const h = React.createElement;
const defaultSentinel = h('div', {style: {width: 1, height: 1}});

export interface InfiniteScrollProps {
interval?: number;
cursor?: number | string;
sentinel?: React.ReactElement<any>;
hasMore?: boolean;
margin?: number;
poll?: number;
loadMore: () => void;
}

Expand All @@ -18,29 +18,62 @@ export interface InfiniteScrollState {

export class InfiniteScroll extends React.Component<InfiniteScrollProps, InfiniteScrollProps> {
static defaultProps = {
interval: 1e3,
sentinel: defaultSentinel,
hasMore: true,
margin: 100,
};

sentinelVisible = false;
lastLoadMoreCursor: number | string | null = null;
timer: any;
mounted: boolean = true;

componentWillUnmount() {
this.mounted = false;
this.stopTimer();
}

startTimer() {
if (this.props.interval) {
this.timer = setTimeout(() => {
if (!this.mounted) return;
if (!this.props.hasMore) return;
if (!this.sentinelVisible) return;
this.loadMore();
this.startTimer();
}, this.props.interval);
}
}

stopTimer() {
clearTimeout(this.timer);
}

onViewportChange = ({visible}) => {
this.sentinelVisible = !!visible;
if (visible) {
if (this.lastLoadMoreCursor !== this.props.cursor) {
this.lastLoadMoreCursor = this.props.cursor;
this.props.loadMore();
}
this.loadMore();
this.startTimer();
} else {
this.stopTimer();
}
};

loadMore() {
if (this.lastLoadMoreCursor !== this.props.cursor) {
this.lastLoadMoreCursor = this.props.cursor;
this.props.loadMore();
}
}

render () {
const {props} = this;
const {children, hasMore, sentinel, margin, poll} = props;
const {children, hasMore, sentinel, margin, interval} = props;
return h(React.Fragment, null,
children,
hasMore &&
h(ViewportScrollSensor, {margin: [0, 0, margin, 0], poll, onChange: this.onViewportChange}, sentinel),
h(ViewportScrollSensor, {margin: [0, 0, margin, 0], poll: interval, onChange: this.onViewportChange}, sentinel),
);
}
}

0 comments on commit fe73c91

Please sign in to comment.