Skip to content

Instantly share code, notes, and snippets.

@AlexFrazer
Created June 8, 2017 21:34
Show Gist options
  • Save AlexFrazer/3909aad4b384c7f976e0f6ebaab01a90 to your computer and use it in GitHub Desktop.
Save AlexFrazer/3909aad4b384c7f976e0f6ebaab01a90 to your computer and use it in GitHub Desktop.
import React, { Component } from 'react';
import styles from './feed.scss';
type Props = {
data: Array<{ id: string }>,
threshold: number,
children: (item: { id: string }, index: number) => React.Element<any>,
};
export default class Feed extends Component {
props: Props;
static defaultProps = {
data: [],
threshold: 1000,
children: () => null,
};
componentDidUpdate({ data }) {
if (this.shouldScroll(data)) {
this.scrollToBottom();
}
}
shouldScroll(prevData) {
const { data, threshold } = this.props;
if (this.getScrollFromBottom() > threshold) {
return false;
}
if (data.length === prevData.length) {
return false;
}
return data.every(({ id }) => prevData.find(({ id: prevId }) => id === prevId);
}
scrollToBottom() {
this.container.scrollTop = this.container.scrollHeight;
}
getScrollFromBottom() {
const { scrollTop, scrollHeight, offsetHeight } = this.container;
return scrollHeight - (scrollTop + offsetHeight);
}
container = null;
render() {
const { children, data } = this.props;
return (
<div
className={styles.container}
ref={el => { this.container = el; }}
>
{data.map(children)}
</div>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment