H5开发之跨页面通讯功能的实现

使用React开发H5是常规的做法,本文就开发实践中遇到的H5开发实现跨页面通讯功能作以记录,希望能够帮助有相同需求的同学。

1. 首先,如果你使用的是React的类组件

如果你的页面是通过React的类组件构建的,那么非常推荐使用Hook来完成这一任务。

1.1. 自定义Hook的基础

自定义Hook允许我们将组件逻辑提取成可重用的函数。在React 16.8之前,状态和副作用的管理通常需要依赖于类组件和生命周期方法。这不仅使得代码重用变得复杂,还增加了组件间状态共享的难度。自定义Hook的出现,使得这些问题迎刃而解。

1.2. 自定义useStorageEventHook解析

自定义的useStorageEvent是一个专门用于监听localStorage中特定键变化的Hook。当指定的键值发生变化时,它将执行提供的回调函数。这在多个组件需要响应相同的存储事件时尤其有用。

1.2.1 实现细节

useStorageEvent Hook利用了React的useEffect Hook来处理副作用------在这个场景中,即是添加和移除事件监听器。useEffect接受一个函数作为参数,这个函数会在组件渲染到屏幕之后执行。更重要的是,useEffect返回的函数会在组件卸载时执行,提供了一个自然的方式来进行清理操作。

javascript 复制代码
useEffect(() => {
  const handleStorageChange = (event) => {
    if (event.key === refreshKey) {
      renderPageByData();
    }
  };

  window.addEventListener('storage', handleStorageChange, false);

  return () => {
    window.removeEventListener('storage', handleStorageChange);
  };
}, [refreshKey, renderPageByData]);

在上述代码中,useEffect的依赖数组[refreshKey, renderPageByData]确保了当这些依赖发生变化时,副作用可以重新执行。这是处理外部事件监听(如localStorage事件)时保持响应性的关键。

1.2.2 事件监听与副作用清理

通过window.addEventListener注册了一个storage事件监听器,当localStorage发生变化时,会调用handleStorageChange函数。如果变化的键匹配refreshKey,则执行renderPageByData回调。利用useEffect的清理机制,通过window.removeEventListener移除事件监听器,避免了内存泄漏和无效的事件处理。

1.3. 自定义Hook的优势

  • 复用性:将逻辑提取到自定义Hook中,可以在多个组件之间共享逻辑,避免了代码的重复。
  • 组织性:自定义Hook允许按逻辑而非生命周期方法组织代码,使得相关代码更加紧密,易于理解和维护。
  • 解耦:自定义Hook帮助将复杂组件拆分成更小、更专注的函数,降低组件间的耦合。

1.4. 完整代码展示

javascript 复制代码
import { useEffect } from 'react';

export const useStorageEvent = (refreshKey, renderPageByData) => {
  useEffect(() => {
    const handleStorageChange = (event) => {
      if (event.key === refreshKey) {
        renderPageByData();
      }
    };

    window.addEventListener('storage', handleStorageChange, false);

    return () => {
      window.removeEventListener('storage', handleStorageChange);
    };
  }, [refreshKey, renderPageByData]);
};

通过useStorageEvent这个例子,我们看到自定义Hook为处理复杂逻辑提供了一种优雅的方法,使得代码不仅易于重用,而且更加清晰和可维护。在现代Web开发实践中,充分利用自定义Hook的优势,可以极大提高开发效率和应用性能。

2. 其次,如果你很不幸的使用了类组件

对于一些老项目来说,业务逻辑都是用React的类组件来写的,因此不能直接使用Hook,这个时候只能退而求其次使用高阶组件实现逻辑复用。

2.1. 高阶组件(HOC)的应用实例

withStorageListener为例,此高阶组件旨在为React类组件提供对localStorage事件的监听功能。当指定的localStorage键值发生变化时,执行预注册的回调函数,从而响应这一变化。这对于需要在多个位置监听并响应相同localStorage变化的应用尤其有用。

2.1.1 实现细节

withStorageListener高阶组件通过封装一个React类组件来实现。在这个类组件的生命周期方法componentDidMount中注册storage事件监听器,在componentWillUnmount中移除监听器。这保证了只有在组件被挂载时监听器才会被添加,而在组件卸载时,相关资源会被正确清理,避免潜在的内存泄露问题。

javascript 复制代码
function withStorageListener(WrappedComponent) {
  return class extends React.Component {
    constructor(props) {
      super(props);
      this.handleStorageChange = this.handleStorageChange.bind(this);
      this.registerCb = { exec: () => {} }
    }

    componentDidMount() {
      window.addEventListener('storage', this.handleStorageChange, false);
    }

    componentWillUnmount() {
      window.removeEventListener('storage', this.handleStorageChange);
      this.registerCb = null;
    }

    handleStorageChange(event) {
      if (event.key === WrappedComponent.refreshKey) {
        if(this.registerCb) this.registerCb.exec();
      }
    }

    render() {
      return <WrappedComponent {...this.props} registerCb={this.registerCb} />;
    }
  };
}

2.1.2 高阶组件的优势

  • 逻辑复用:HOC使得跨组件的逻辑复用成为可能,尤其适用于将相同的逻辑应用到多个组件上。
  • 抽象和隔离:HOC可以将复杂的逻辑和状态抽象隔离,简化被包装组件的实现,使其更关注于渲染逻辑。
  • 链式组合:HOC可以被链式组合使用,为组件逐步增加多个功能或增强。

2.2 比较

虽然高阶组件和自定义Hook各有千秋,它们在React生态中都扮演着重要角色。高阶组件以其强大的逻辑封装和复用能力,依旧是React应用开发中不可或缺的一部分。而自定义Hook则以其简洁和直观的用法,为函数式组件提供了强大的状态管理和逻辑复用能力。

javascript 复制代码
// 导出高阶组件
export { withStorageListener };

高阶组件和自定义Hook不是相互排斥的,它们可以根据不同的场景和需求被灵活选用。例如,对于需要在函数式组件中共享逻辑的情况,自定义Hook可能是更佳选择;而对于希望在多个类组件中复用逻辑的场景,高阶组件则能够发挥其独特的优势。正确地理解和运用这两种模式,将有助于提高React应用的开发效率和代码的可维护性。

3. 结尾

本文从实际开发的一个需求入手,不仅记录了如何解决H5开发过程中跨页面通讯的问题,还结合代码对比了两种逻辑复用解决方案,即Hook和HOC的不同。

相关推荐
阿伟来咯~2 小时前
记录学习react的一些内容
javascript·学习·react.js
吕彬-前端2 小时前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱2 小时前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
bysking3 小时前
【前端-组件】定义行分组的表格表单实现-bysking
前端·react.js
September_ning7 小时前
React.lazy() 懒加载
前端·react.js·前端框架
web行路人7 小时前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
番茄小酱0017 小时前
Expo|ReactNative 中实现扫描二维码功能
javascript·react native·react.js
Rattenking9 小时前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js
熊的猫11 小时前
JS 中的类型 & 类型判断 & 类型转换
前端·javascript·vue.js·chrome·react.js·前端框架·node.js
小牛itbull15 小时前
ReactPress:重塑内容管理的未来
react.js·github·reactpress