ReactJS中eval失效,如何以模板字面量为变量名引用已导入的Redux Action模块
为什么你现在的eval实现跑不通
你靠模板字符串拼变量名、用eval求值找模块的方案失效,本质是三个硬伤:
- 你拼出来的
${reducer}Actions对应的变量,是ES模块的导入绑定,这类绑定属于模块顶层作用域,根本不暴露给eval的默认求值上下文,大概率会直接抛ReferenceError - 就算你在裸浏览器环境碰运气跑通了,只要代码经过Webpack、Vite这类打包工具做作用域隔离,所有导入的变量都会被重命名成带hash的短名称,你拼的字符串根本对不上真实的变量名,到生产环境必然崩
- eval本身带代码注入风险,在Redux这类核心业务链路里用完全是反模式,完全没有必要为了少写几行映射冒这个险
可直接落地的实现方案
根本不需要动态求变量名,手动搭一个字符串到模块的映射表就行,整个逻辑是静态可追踪的,不管啥运行环境、啥打包工具都能正常跑:
- 保留你原本写的三个actionTypes模块的导入逻辑
- 建一个普通对象当映射表,把你允许传入的reducer字符串当key,对应导入的模块当value
- 函数执行时直接用传入的reducer字符串当key,从映射表里取到对应的模块,再读对应的action type就行
替换后的代码:
// These are redux action types import * as fileTypeOneActions from "./fileTypeOne/actionTypes" import * as fileTypeTwoActions from "./fileTypeTwo/actionTypes" import * as fileTypeThreeActions from "./fileTypeThree/actionTypes" // 维护传入值与对应action类型模块的映射关系 const actionModuleMap = { fileTypeOne: fileTypeOneActions, fileTypeTwo: fileTypeTwoActions, fileTypeThree: fileTypeThreeActions } export const updateApiResponse = (reducer, apiResponse) => { // 支持的reducer入参为 "fileTypeOne" / "fileTypeTwo" / "fileTypeThree" const targetModule = actionModuleMap[reducer] // 加个简单校验,传错值的时候抛明确的错误,比顺着undefined往下跑报错好排查 if (!targetModule) { throw new Error(`未匹配到对应reducer: ${reducer},支持的取值为fileTypeOne/fileTypeTwo/fileTypeThree`) } return { type: targetModule.UPDATE_API_RESPONSE, apiResponse: apiResponse, } }
几个实际开发里的注意点
- 这种映射写法是完全静态的,打包工具能准确识别所有依赖,不会出现动态导入漏包、变量重命名错位的问题
- 后续新增其他类型的reducer,只需要导入对应的actionTypes模块,在映射表里加一行key-value就行,3个模块的时候手动写映射的成本低到可以忽略,比写动态求值的逻辑好维护太多
- 如果同路径下的actionTypes模块数量多到手动写映射嫌麻烦,可以用Vite/Webpack提供的
import.meta.glob批量导入对应路径下的所有模块,自动生成结构完全一样的映射表——但这本质还是静态映射,不是动态求变量名,核心逻辑没有任何区别
别为了省几行代码走动态取变量名的路子,前端工程化场景下这类动态逻辑的长期排查、维护成本,比写几行静态映射高太多了
内容的提问来源于stack exchange,提问作者DLateef
相关产品推荐
相关产品推荐

