React中的useSyncExternalStore使用

官方的解释是useSyncExternalStore 是一个让你订阅外部 store 的 React Hook。😄官方就爱打马虎眼,这样说随能一下子明白它的作用,接下来我们就来仔细的讲解下它的作用和应用场景。

useSyncExternalStore 作为 React 18 引入的一个 Hook,主要用于订阅外部数据源,确保在并发渲染下数据的一致性。它主要用于:

  • 订阅浏览器 API(如 window.width)
  • 订阅第三方状态管理库
  • 订阅任何外部数据源

直接上例子:

  • 基本语法

    const state = useSyncExternalStore(
    subscribe, // 订阅函数
    getSnapshot, // 获取当前状态的函数
    getServerSnapshot // 可选:服务端渲染时获取状态的函数
    );

  • 实战 浏览器网络状态

    //useOnlineStatus hooks
    import { useSyncExternalStore } from 'react';

    export function useOnlineStatus() {
    const isOnline = useSyncExternalStore(subscribe, getSnapshot);
    return isOnline;
    }

    function getSnapshot() {
    return navigator.onLine;
    }

    function subscribe(callback) {
    window.addEventListener('online', callback);
    window.addEventListener('offline', callback);
    return () => {
    window.removeEventListener('online', callback);
    window.removeEventListener('offline', callback);
    };
    }

  • 实战浏览器窗口宽高

    // useWindowSize hooks
    function useWindowSize() {
    const getSnapshot = () => ({
    width: window.innerWidth,
    height: window.innerHeight
    });

    复制代码
    const subscribe = (callback) => {
      window.addEventListener('resize', callback);
      return () => window.removeEventListener('resize', callback);
    };
    
    return useSyncExternalStore(subscribe, getSnapshot);

    }

    // 组建中 hooks使用
    function NavComponent() {
    const { width, height } = useWindowSize();

    复制代码
    return (
      <div>
        Window size: {width} x {height}
      </div>
    );

    }

  • 实战 切换主题

    function createThemeStore() {
    let theme = 'light';
    const listeners = new Set();

    复制代码
    return {
      subscribe(listener) {
        listeners.add(listener);
        return () => listeners.delete(listener);
      },
      getSnapshot() {
        return theme;
      },
      toggleTheme() {
        theme = theme === 'light' ? 'dark' : 'light';
        listeners.forEach(listener => listener());
      }
    };

    }

    const themeStore = createThemeStore();

    function useTheme() {
    return useSyncExternalStore(
    themeStore.subscribe,
    themeStore.getSnapshot
    );
    }

    function ThemeToggle() {
    const theme = useTheme();

    复制代码
    return (
      <button onClick={() => themeStore.toggleTheme()}>
        Current theme: {theme}
      </button>
    );

    }

注意事项

  1. 保持一致性

    • subscribe 函数应该返回清理函数
    • getSnapshot 应该返回不可变的数据
  2. 避免频繁更新

    • 考虑使用节流或防抖
    • 实现选择性订阅机制
  3. 服务端渲染

    • 提供 getServerSnapshot
    • 确保服务端和客户端状态同步
  4. 内存管理

    • 及时清理订阅
    • 避免内存泄漏
相关推荐
sbjdhjd3 小时前
Redis 主从复制、哨兵高可用与 Cluster 集群部署实验手册
运维·前端·redis·云原生·开源·bootstrap·html
乐兮创想 小林3 小时前
企业官网移动端性能优化实战:从 Core Web Vitals 到图片/CDN/响应式的工程清单
前端·性能优化·网站建设·北京网站建设公司
疯狂SQL4 小时前
JWT 在线解码、验签、生成一篇讲透:附前端实现、工具架构与在线体验地址
javascript·jwt·编解码·jwt测试
前端一小卒4 小时前
不手写代码的第 30 天,我才明白前端这个岗位还剩什么
前端·javascript·ai编程
Ajie'Blog4 小时前
Copilot Agent Tasks API 开放:AI 编程开始进入后台任务时代
服务器·前端·javascript·人工智能·copilot·ai编程
老毛肚4 小时前
jeecgboot vue TS & 模板化 04
前端·javascript·vue.js
晓13134 小时前
【Cocos Creator 2.x】篇——第二章 入门
javascript·游戏引擎
AI_零食5 小时前
鸿蒙PC Electron跨平台应用开发:24时区时间表应用详解
前端·华为·electron·开源·harmonyos·鸿蒙
Electrolux6 小时前
[onlyoffice-v9]纯前端怎么实现编辑预览office
前端·javascript·github
VidDown6 小时前
Webhook 调试器:让第三方回调“原形毕露”
java·开发语言·javascript·编辑器·postman