将读取window数据的const定义在React组件外,能否保证正常初始化?
结论
只要你的项目满足以下两个前提,移到组件外部的初始化代码就100%每次都能正常执行,window["my-app"]["data"]一定可用:
- 你在
head中写的初始化全局数据的script标签是不带async/defer属性的同步脚本 - 你的TSX打包后的JS脚本,是放在初始化
script标签之后加载的(比如常规放在body底部的引入方式)
原理说明
浏览器解析HTML是严格从上到下的顺序执行同步脚本:
- 首先会执行
head里的初始化脚本,给window挂载my-app数据,执行完成后才会继续解析后续的DOM和JS资源 - 模块顶层的代码会在模块被加载时立即执行,你的组件脚本加载时机晚于初始化脚本,所以解构时数据必然已经存在
注意事项
- 如果你的项目用到了服务端渲染(SSR/SSG,比如Next.js、Gatsby等),不能直接在模块顶层访问
window,服务端环境不存在window对象会直接报错,建议改成延迟取值的写法:
// 封装成工具函数,运行时取值,避免服务端报错 const getAppData = () => { if (typeof window === 'undefined') return {} return window['my-app']?.data ?? {} } // 用到的时候再调用取值 const function1 = () => { const {a, b} = getAppData() // 业务逻辑 }
- 为了TS类型安全,建议给全局
Window对象补充类型声明:
// 可以放在项目的global.d.ts文件中 declare global { interface Window { 'my-app': { data: { a: string b: number c: string d: boolean // 补充其他字段的类型定义 } } } }
- 可以加可选链兜底判断,避免极端场景下的报错:
const {a, b, c, d} = window?.['my-app']?.data ?? {}
内容的提问来源于stack exchange,提问作者Thiyagu
相关产品推荐
相关产品推荐

