向Loadable的loader传递参数:子组件预加载初始数据问题
使用Loadable.Map预加载子组件初始数据的正确姿势
嘿,我完全get你的需求——通过Loadable.Map异步加载Catalog组件的同时,提前拉取它需要的初始数据,等组件和数据都准备好再渲染,避免那种先出骨架屏再加载数据的闪烁感对吧?
先把你没写完的代码补全并修正成可运行的版本,关键就在render函数里如何拿到预加载的数据并传递给Catalog:
import Loadable from 'react-loadable'; // 先确认你的数据获取函数返回Promise(Loadable.Map依赖这个等待数据就绪) const fetchCatalogInitialData = (foo1, foo2) => { // 示例:调用后端接口获取初始数据 return fetch(`/api/catalog/initial?foo1=${foo1}&foo2=${foo2}`) .then(res => { if (!res.ok) throw new Error('数据加载失败'); return res.json(); }); }; // 用Loadable.Map定义异步加载的Catalog组件 const Catalog = Loadable.Map({ loader: { // 异步加载Catalog组件文件 Catalog: () => import('./Catalog'), // 并行预取初始数据,传入你的参数foo1、foo2 initialData: () => fetchCatalogInitialData(foo1, foo2), }, // 加载过程中显示的占位UI loading: () => <div>加载中...</div>, // 所有资源(组件+数据)加载完成后执行的渲染逻辑 render(loaded, props) { // 注意:ES模块默认导出的组件在default属性下 const CatalogComponent = loaded.Catalog.default; // 取出预加载完成的初始数据 const initialData = loaded.initialData; // 把初始数据作为props传给Catalog组件 return <CatalogComponent {...props} initialData={initialData} />; }, }); // 父组件A中直接使用这个异步加载的Catalog const ComponentA = () => { return ( <div className="parent-component"> <h2>父组件A</h2> <Catalog /> </div> ); };
这里有几个关键细节要注意,不然容易踩坑:
- 数据函数必须返回Promise:
fetchCatalogInitialData一定要返回Promise,Loadable.Map会等待这个Promise resolve后才会触发render。如果你的函数是同步的,记得用Promise.resolve()包装一下。 - 正确获取加载后的组件:如果你的Catalog组件是用
export default导出的,就必须取loaded.Catalog.default;如果是命名导出(比如export const Catalog = () => {}),就直接取loaded.Catalog.Catalog。 - 动态参数的处理:如果
foo1和foo2是父组件的动态props(比如从路由、接口获取的),那Loadable.Map初始化时的loader函数是拿不到这些动态值的。这种情况下,你可以先在父组件里等参数就绪后再渲染Catalog:
const ComponentA = () => { const [foo1, setFoo1] = useState(null); const [foo2, setFoo2] = useState(null); // 假设参数是从路由或者接口获取的 useEffect(() => { const fetchParams = async () => { const { foo1, foo2 } = await getRouteParams(); setFoo1(foo1); setFoo2(foo2); }; fetchParams(); }, []); // 等参数就绪后再渲染Catalog,确保预加载数据时能拿到正确参数 if (!foo1 || !foo2) { return <div>准备中...</div>; } return ( <div className="parent-component"> <h2>父组件A</h2> <Catalog /> </div> ); };
总的来说,Loadable.Map的核心就是帮你并行处理组件代码的异步加载和数据的预获取,等两者都完成后一次性渲染,完美解决初始数据加载的时机问题。
内容的提问来源于stack exchange,提问作者Chuck
相关产品推荐
相关产品推荐

