События onPause и onResume для моего компонента React не работают - PullRequest
0 голосов
/ 16 марта 2020

У меня есть компонент 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>
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...