NextJS getStaticProps传值组件时缺失legalDocuments属性报错
问题原因
这个TS报错由两个核心问题导致:
- 你定义的组件
Props类型仅声明了documentType字段,但组件实际解构接收了legalDocuments参数,TS自动推导组件要求传入两个必填参数,和手动定义的Props类型不匹配。 - Next.js的
getStaticProps生命周期仅会在pages目录下的页面级组件中执行,普通公共组件里编写的getStaticProps不会运行,自然也不会自动把legalDocuments注入到组件props中。就算给Props补上legalDocuments类型,直接调用组件时还是需要手动传入该参数,不符合你只传documentType的使用需求。
可行解决方案
方案1:将文档加载逻辑内聚到组件中(推荐,符合使用预期)
把markdown文件读取逻辑直接放到组件内部,不需要依赖外部传入legalDocuments,调用组件时仅需传入documentType即可。注意要给nodejs原生API加环境判断,避免客户端打包时执行fs相关逻辑报错。
修正后的完整代码如下:
import marked from 'marked'; import getConfig from 'next/config'; import path from 'path'; import fs from 'fs'; import { useRouter } from 'next/router'; // 限定合法的文档类型,避免传参错误 type DocumentType = 'legalNotice' | 'privacyPolicy' | 'termsOfService' type Props = { documentType: DocumentType } const LegalDocument = ({ documentType }: Props) => { const { locale, defaultLocale } = useRouter(); let documentContent = '' // 仅在服务端环境执行文件读取,避免客户端打包报错 if (typeof window === 'undefined') { const { serverRuntimeConfig } = getConfig() // 入参与实际文件名的映射关系 const fileKeyMap: Record<DocumentType, string> = { legalNotice: 'legal_notice', privacyPolicy: 'privacy_policy', termsOfService: 'terms_of_service' } const supportLangs = ['de', 'en', 'es', 'fr', 'it'] // 优先匹配当前语言,匹配失败回退到默认语言 const targetLang = supportLangs.includes(locale as string) ? locale : defaultLocale try { const filePath = path.join( serverRuntimeConfig.PROJECT_ROOT, './legal', `${fileKeyMap[documentType]}.${targetLang}.md` ) documentContent = marked.parse(fs.readFileSync(filePath, 'utf8')) } catch (e) { // 读取失败兜底 documentContent = documentType } } return ( <div dangerouslySetInnerHTML={{ __html: documentContent }} /> ) } export default LegalDocument
注意:
marked解析后返回的是HTML字符串,直接通过{变量}渲染会把标签转义为普通文本,需要用dangerouslySetInnerHTML才能正常渲染富文本格式。
方案2:保留getStaticProps逻辑,作为页面级组件使用
如果你需要保留getStaticProps的预加载逻辑,可以把该组件放到pages目录下作为页面组件使用,同时补全Props类型定义:
// 补全完整的Props类型 type LegalDocLocaleMap = Record<string, string> type LegalDocuments = Record<DocumentType, LegalDocLocaleMap> type Props = { documentType: DocumentType, legalDocuments: LegalDocuments }
该方案的缺点是无法在其他公共组件中直接通过<LegalDocument documentType="legalNotice" />的方式调用,只能通过路由参数传递documentType,由页面的getStaticProps预加载数据后传递给组件渲染。
内容的提问来源于stack exchange,提问作者Florian
相关产品推荐
相关产品推荐

