如何在 React 中实现一个自定义 Hook 来监听页面可见性(Page Visibility)状态的变化?

如何在 React 中实现一个自定义 Hook 来监听页面可见性(Page Visibility)状态的变化?

回答与解析:

可以使用浏览器的 Page Visibility API(document.visibilityState 和 visibilitychange 事件)结合 useEffect 和 useState 来创建一个自定义 Hook。示例如下:

import { useState, useEffect } from 'react';

function usePageVisibility(): boolean {
  const [isVisible, setIsVisible] = useState(() => {
    // 初始状态:如果 document 不可用(如 SSR),默认为 true
    return typeof document !== 'undefined' ? document.visibilityState === 'visible' : true;
  });

  useEffect(() => {
    const handleVisibilityChange = () => {
      setIsVisible(document.visibilityState === 'visible');
    };

    // 添加事件监听
    document.addEventListener('visibilitychange', handleVisibilityChange);

    // 清理监听器
    return () => {
      document.removeEventListener('visibilitychange', handleVisibilityChange);
    };
  }, []);

  return isVisible;
}

// 使用示例
function MyComponent() {
  const isVisible = usePageVisibility();

  return (
    <div>
      页面当前{isVisible ? '可见' : '不可见'}
    </div>
  );
}

解析:

  • Page Visibility API 提供了 document.visibilityState(值为 'visible'、'hidden'、'prerender' 等)和 visibilitychange 事件。
  • 自定义 Hook usePageVisibility 封装了状态管理和事件监听逻辑,返回一个布尔值表示页面是否可见。
  • 使用 useEffect 在组件挂载时添加事件监听,并在卸载时移除,避免内存泄漏。
  • 初始状态使用函数形式的 useState,防止在服务端渲染(SSR)环境下访问 document 报错。
  • 该 Hook 可用于暂停视频播放、停止轮询请求、暂停动画等优化场景。

发表评论 (审核通过后显示评论):

昵称:
邮箱:
内容: