SPFx集成SP PnP v3时出现pageContext未定义的TypeError错误
SPFx + SP PnP v3开发WebPart报错:TypeError: Cannot read properties of undefined (reading 'pageContext')
问题背景
我参考官方教程使用SPFx结合SP PnP v3开发WebPart,相关代码及报错如下:
根.ts文件代码
public async onInit(): Promise<void> { await super.onInit(); getSP(this.context); }
父组件代码
import { getSP } from "../components/pnpjsConfig"; import { SPFI, spfi } from "@pnp/sp"; let sp: SPFI; sp = getSP(); const GetAssessments = async () => { const allItems = await sp.web.lists.getByTitle("MyList").items.select(`*, Author/Id, CompletedBy/UserName, CompletedBy/Title, CompletedBy/Id, BURepresentative/UserName, BURepresentative/Title, BURepresentative/Id `).expand('Author, CompletedBy, BURepresentative')().then(r => { const returnedAssessment: IListItem[] = r.map((item) => { return { Id: item.Id, FormStatus: item.FormStatus, CurrentStatus: item.CurrentStatus, CompletedById: item.CompletedById, AuthorId: item.AuthorId, BURepresentativeId: item.BURepresentativeId, }; }); return returnedAssessment; }); let sortedAssessment = allItems.sort((a, b) => a.Id < b.Id ? 1 : -1); return sortedAssessment; };
报错信息
执行gulp serve --nobrowser命令时出现如下错误:
TypeError: Cannot read properties of undefined (reading 'pageContext')
问题原因
错误根源在于提前调用了未初始化的SP实例:父组件中直接在全局作用域执行sp = getSP(),此时WebPart的onInit方法还未调用getSP(this.context)完成上下文注入,导致返回的SP实例未关联有效的pageContext,后续调用sp.web时触发报错。
解决方案
1. 调整父组件代码,延迟获取SP实例
将sp = getSP()移到GetAssessments函数内部,确保只有在函数执行时(此时WebPart已完成初始化)才获取已注入上下文的SP实例:
import { getSP } from "../components/pnpjsConfig"; import { SPFI, spfi } from "@pnp/sp"; const GetAssessments = async () => { // 确保在函数执行时获取已初始化的SP实例 const sp = getSP(); if (!sp) { throw new Error("SP上下文未完成初始化,请检查WebPart的onInit方法"); } const allItems = await sp.web.lists.getByTitle("MyList").items.select(`*, Author/Id, CompletedBy/UserName, CompletedBy/Title, CompletedBy/Id, BURepresentative/UserName, BURepresentative/Title, BURepresentative/Id `).expand('Author, CompletedBy, BURepresentative')().then(r => { const returnedAssessment: IListItem[] = r.map((item) => { return { Id: item.Id, FormStatus: item.FormStatus, CurrentStatus: item.CurrentStatus, CompletedById: item.CompletedById, AuthorId: item.AuthorId, BURepresentativeId: item.BURepresentativeId, }; }); return returnedAssessment; }); let sortedAssessment = allItems.sort((a, b) => a.Id < b.Id ? 1 : -1); return sortedAssessment; };
2. 确保pnpjsConfig.ts的getSP实现正确
检查pnpjsConfig.ts中的getSP函数,确保它正确存储并返回初始化后的SPFI实例:
import { SPFI, spfi, SPFx } from "@pnp/sp"; import "@pnp/sp/webs"; import "@pnp/sp/lists"; import "@pnp/sp/items"; // 存储全局SP实例,初始为null let _sp: SPFI | null = null; export const getSP = (context?: any): SPFI => { // 仅当实例未初始化且传入上下文时,创建新的SP实例 if (_sp === null && context) { _sp = spfi().using(SPFx(context)); } // 返回已初始化的实例 return _sp!; };
验证
修改代码后重新执行gulp serve --nobrowser,WebPart应能正常初始化并获取列表数据,不再触发pageContext未定义的错误。
内容的提问来源于stack exchange,提问作者NightTom
相关产品推荐
相关产品推荐

