React组件渲染报TypeError: x.IndexPage is not a function错误如何解决
问题原因及解决方法
错误原因
- 你定义的async IIFE执行后返回的是
Promise对象,而非你内部return的包含IndexPage的普通对象。组件初始化渲染是同步执行的,此时Promise还处于pending状态,自然不存在x.IndexPage方法,才会抛出该类型错误。 - 这种动态加载第三方库避免打入主包的思路是可行的,只是写法不符合异步逻辑和React组件的渲染规则。
正确实现方案
这里提供两种符合Next.js规范的实现方式:
方案1:在组件内部通过useEffect动态加载moment
import Link from "next/link"; import { useEffect, useState } from "react"; export default function IndexPage() { const [moment, setMoment] = useState(null); // 组件挂载后异步加载moment useEffect(() => { import("moment").then(mod => { setMoment(mod.default); }); }, []); // 加载完成前可以渲染占位内容 if (!moment) return <div>加载中...</div>; console.log(moment().format("DD-MM-YYYY")); return ( <div> Hello World.{" "} <Link href="/about"> <a>Abouthhhh</a> </Link> </div> ); }
方案2:使用Next.js的dynamic方法封装带moment依赖的组件
你也可以把依赖moment的逻辑单独抽离成组件,用Next.js内置的dynamic方法异步加载,同样不会打入主包:
// 单独新建组件文件 MomentComponent.js import moment from "moment"; export default function MomentComponent() { console.log(moment().format("DD-MM-YYYY")); return <div>{moment().format("DD-MM-YYYY")}</div>; } // 页面组件中引入 import Link from "next/link"; import dynamic from "next/dynamic"; const MomentComponent = dynamic(() => import("../components/MomentComponent"), { loading: () => <div>加载中...</div> }); export default function IndexPage() { return ( <div> Hello World.{" "} <Link href="/about"> <a>Abouthhhh</a> </Link> <MomentComponent /> </div> ); }
两种方案都可以实现moment代码分离,不会被打入初始主包,达到优化首屏性能的效果。
内容的提问来源于stack exchange,提问作者user944513
相关产品推荐
相关产品推荐

