У меня есть компонент TodayPage. Его роль заключается в отображении последних сообщений пользователя. Зная, что я использую React с Cordova в своем приложении, я хочу использовать события onPause и onResume для автоматического обновления sh страницы, когда приложение находится в фоновом режиме более 15 минут. В onPause должна храниться дата, а onResume вычисляет разницу между датой в onPause и обновляет sh страницу, если она длилась более 15 минут.
Как я могу сделать это с жизненным циклом компонента React? Я безуспешно пробовал несколько вещей, должен ли я использовать состояние?
Это мой компонент с моим текущим кодом, где я пытался поместить слушателей с жизненным циклом, но он не работает:
const FETCH_LIMIT = 5;
const reloadTime = 10000;
let pauseDate;
let resumeDate;
class TodayPage extends PureComponent {
static propTypes = {
loadMorePosts: PropTypes.func.isRequired,
morePosts: PropTypes.object,
onReady: PropTypes.func.isRequired,
posts: PropTypes.object.isRequired,
refreshPosts: PropTypes.func.isRequired,
}
static contextTypes = {
apiURL: PropTypes.string,
};
static defaultProps = {
morePosts: {},
}
constructor(props) {
super(props);
this.node = React.createRef();
}
state = {
isInfiniteEnabled: false,
items: [],
onRefreshDone: () => null,
}
componentDidMount() {
this.node.current.refs.el.querySelector('.page-content').addEventListener('scroll', this.toggleVisibility);
document.addEventListener('pause', this.onPause);
document.addEventListener('resume', this.onResume);
}
componentDidUpdate(prevProps) {
const { posts, morePosts, onReady } = this.props;
const { onRefreshDone, items } = this.state;
/* Refresh using infinite */
if (
!posts.refreshing &&
prevProps.posts.refreshing
) {
onRefreshDone();
this.setState({ items: posts.value, isInfiniteEnabled: posts.value.length >= FETCH_LIMIT });
}
/* First request */
if (prevProps.posts.pending && !posts.pending && posts.fulfilled) {
this.setState({ items: posts.value, isInfiniteEnabled: posts.value.length >= FETCH_LIMIT });
onReady();
}
/* When user scrolls done in the infinite page, add more posts */
if (prevProps.morePosts.pending && !morePosts.pending && morePosts.fulfilled) {
const newState = { items: items.concat(morePosts.value) };
// no more available articles
if (morePosts.value.length < FETCH_LIMIT) {
newState.isInfiniteEnabled = false;
}
this.setState(newState);
}
}
componentWillUnmount() {
this.node.current.refs.el.querySelector('.page-content').removeEventListener('scroll', this.toggleVisibility);
document.removeEventListener('pause', this.onPause);
document.removeEventListener('resume', this.onResume);
}
onPause = () => {
pauseDate = new Date();
}
onResume = () => {
resumeDate = new Date();
const dateDiff = resumeDate - pauseDate;
if (dateDiff >= reloadTime) {
window.location.reload();
}
}
refresh = (event, done) => {
const { refreshPosts } = this.props;
this.setState({
onRefreshDone: done,
});
refreshPosts();
}
loadMore = () => {
const { items } = this.state;
const { loadMorePosts, morePosts } = this.props;
if (morePosts.pending) return;
loadMorePosts(items.length);
}
toggleVisibility = () => {
const isTopButtonVisible = this.node.current.refs.el.querySelector('.page-content').scrollTop > 150;
this.setState({
isTopButtonVisible,
});
}
scrollToTop = () => {
/* Scroll to the top of the page with smooth scroll movment */
this.node.current.refs.el.querySelector('.page-content').scrollTo({
top: 0,
behavior: 'smooth',
});
}
render() {
const { posts } = this.props;
const { isInfiniteEnabled, items, isTopButtonVisible } = this.state;
const isBetaVersion = Number(process.env.REACT_APP_IS_BETA);
return (
<Page
id="page-relative"
noNavbar
ptr
onPtrRefresh={this.refresh}
infinite
infiniteDistance={70}
onInfinite={isInfiniteEnabled ? this.loadMore : () => null}
infinitePreloader={isInfiniteEnabled}
ref={this.node}
onPause={this.onPause}
onResume={this.onResume}
>
{isBetaVersion && (
<CornerSticker corner={CornerSticker.SIDE.UPPER_RIGHT}>
<FormattedMessage id="press_yui_beta_version" />
</CornerSticker>
)}
<Block id="today-content">
<div className="title-container">
<h1>
<FormattedMessage id="press_yui_home_title" />
</h1>
</div>
{posts.rejected && (
<span>
{' '}
{posts.reason}
</span>
)}
{posts.pending && (
<Block className="row align-items-stretch text-align-center">
<Col><Preloader size={50} /></Col>
</Block>
)}
{!!(posts.fulfilled && !items.length) && (
<Block>
<Col>
<FormattedMessage id="press_yui_home_empty" />
</Col>
</Block>
)}
{ !!(posts.fulfilled && items.length) && items.map((article) => (
<ArticleCard
article={article}
key={article._id}
date={article.publicationDate || article.createdAt}
url={`/articles/${article._id}`}
category={article.category.name}
routeProps={{ article }}
/>
))}
</Block>
<GoTopButton
onClick={this.scrollToTop}
isVisible={isTopButtonVisible}
/>
</Page>
);
}
}