当前位置: 首页 > article >正文

26.useScript

在 Web 应用开发中,动态加载外部脚本是一个常见需求,特别是在需要集成第三方库或服务时。然而,在 React 应用中管理脚本加载可能会变得复杂。useScript 钩子提供了一种优雅的方式来处理外部脚本的加载、错误处理和清理,使得在 React 组件中动态加载脚本变得简单和可靠。以下是如何实现和使用这个自定义钩子:

const useScript = src => {
  const [status, setStatus] = React.useState(src ? 'loading' : 'idle');

  React.useEffect(() => {
    if (!src) {
      setStatus('idle');
      return;
    }

    let script = document.querySelector(`script[src="${src}"]`);

    if (!script) {
      script = document.createElement('script');
      script.src = src;
      script.async = true;
      script.setAttribute('data-status', 'loading');
      document.body.appendChild(script);

      const setDataStatus = event => {
        script.setAttribute(
          'data-status',
          event.type === 'load' ? 'ready' : 'error'
        );
      };
      script.addEventListener('load', setDataStatus);
      script.addEventListener('error', setDataStatus);
    } else {
      setStatus(script.getAttribute('data-status'));
    }

    const setStateStatus = event => {
      setStatus(event.type === 'load' ? 'ready' : 'error');
    };

    script.addEventListener('load', setStateStatus);
    script.addEventListener('error', setStateStatus);

    return () => {
      if (script) {
        script.removeEventListener('load', setStateStatus);
        script.removeEventListener('error', setStateStatus);
      }
    };
  }, [src]);

  return status;
};

const script =
  'data:text/plain;charset=utf-8;base64,KGZ1bmN0aW9uKCl7IGNvbnNvbGUubG9nKCdIZWxsbycpIH0pKCk7';

const Child = () => {
  const status = useScript(script);
  return <p>Child status: {status}</p>;
};

const MyApp = () => {
  const status = useScript(script);
  return (
    <>
      <p>Parent status: {status}</p>
      <Child />
    </>
  );
};

ReactDOM.createRoot(document.getElementById('root')).render(
  <MyApp />
);

这个技巧的关键点包括:

  1. 使用 useState 来跟踪脚本的加载状态。

  2. 使用 useEffect 来处理脚本的加载、错误处理和清理逻辑。

  3. 检查是否已存在相同 src 的脚本元素,避免重复加载。

  4. 使用 data-status 属性来跟踪脚本的加载状态。

  5. 添加事件监听器来处理加载成功和失败的情况。

使用这个钩子时,需要注意以下几点:


http://www.kler.cn/a/525030.html

相关文章:

  • 如何将DeepSeek部署到本地电脑
  • Shell特殊状态变量以及常用内置变量总结
  • Kmesh v1.0 正式发布
  • 用JavaScript实现观察者模式
  • 小白爬虫冒险之反“反爬”:无限debugger、禁用开发者工具、干扰控制台...(持续更新)
  • 【16届蓝桥杯寒假刷题营】第2期DAY4
  • 安卓逆向之脱壳-认识一下动态加载 双亲委派(二)
  • 洛谷P3383 【模板】线性筛素数
  • 在Visual Studio Code自带的按键编译无法使用该怎么办
  • JavaScript_01
  • Baklib如何重新定义企业知识管理提升组织效率与创新力
  • MyBatis 缓存机制详解
  • Java学习教程,从入门到精通,JDBC 删除表语法及案例(103)
  • 基于Langchain-Chatchat + ChatGLM 本地部署知识库
  • 240. 搜索二维矩阵||
  • 【JavaEE】Spring(6):Mybatis(下)
  • docker安装emqx
  • 11JavaWeb——SpringBootWeb案例02
  • S4 HANA明确Tax Base Amount是否考虑现金折扣(OB69)
  • 蓝桥杯python语言基础(4)——基础数据结构(下)