如何在React中实现条件或动态导入多个模块,减少冗余导入代码?
解决方案
你可以通过批量导入的方式完全省去逐个写import和手动维护lessons对象的代码,后续新增数据文件不需要修改当前逻辑,自动生效。
方案1:全量批量导入(适合文件总数较少的场景)
一次性导入所有数据模块,和你现有使用逻辑完全兼容,不用修改后续业务代码。
如果你用 Webpack/CRA 搭建项目
使用require.context接口实现批量导入,替换你原有所有导入语句和手动声明的lessons对象即可:
import React from "react"; // 批量匹配../data目录下所有Mod开头、Data结尾的js/ts文件 const modFileContext = require.context('../data', false, /Mod\d+Data\.(js|ts)$/) const lessons = modFileContext.keys().reduce((result, filePath) => { // 从文件路径提取模块名,例如 ./Mod1Data.js → Mod1Data const moduleName = filePath.replace(/^\.\/(.*)\.\w+$/, '$1') const moduleContent = modFileContext(filePath) // 兼容export default和直接导出的两种写法 result[moduleName] = moduleContent.default ?? moduleContent return result }, {})
如果你用 Vite 搭建项目
使用import.meta.glob接口实现批量导入:
import React from "react"; // 批量匹配../data目录下所有Mod开头、Data结尾的js/ts文件,eager参数代表同步加载 const modFileMap = import.meta.glob('../data/Mod*Data.(js|ts)', { eager: true }) const lessons = Object.keys(modFileMap).reduce((result, filePath) => { // 从文件路径提取模块名,例如 ../data/Mod1Data.js → Mod1Data const moduleName = filePath.match(/Mod\d+Data/)[0] const moduleContent = modFileMap[filePath] result[moduleName] = moduleContent.default ?? moduleContent return result }, {})
上述两种实现写完后,你原有的业务逻辑不需要做任何修改,新增Mod8Data、Mod9Data等文件时,只要放到../data目录下就会被自动识别导入。
方案2:按需动态导入(适合后续文件数量较多的场景)
如果后续文件数量会增长到几十上百个,可以选择切换lesson时才加载对应的数据文件,降低首屏体积:
import React, { useState, useEffect } from "react"; const [currentData, setCurrentData] = useState(null) // 可选:添加loading状态处理加载时延 const [loading, setLoading] = useState(false) useEffect(() => { const loadLessonData = async () => { setLoading(true) // 动态导入对应lesson的数据文件 const module = await import(`../data/Mod${lesson}Data.js`) setCurrentData(module.default ?? module) setLoading(false) localStorage.setItem("lesson", JSON.stringify(lesson)); } loadLessonData() }, [lesson]) const properties = { lesson: lesson, data: currentData, }; if (loading) return <div>加载中...</div> return ( <div> <Component {...properties} /> </div> );
内容的提问来源于stack exchange,提问作者lache
相关产品推荐
相关产品推荐

