是否可以在DetailsList中调用async函数获取SPO列表数据?
问题解答
报错原因
你遇到的类型报错是因为async函数的返回值本质是Promise对象,而Fluent UI的DetailsList组件items属性要求传入的是实际的数组类型,直接将异步函数返回的Promise赋值给items自然会出现类型不匹配的问题。
同时你现有的getTabData方法还存在两个问题:
- 缺少
return语句,即使异步执行完成也无法返回获取到的列表项数组 - 存在一行多余的未接收返回值、未加
await的SPO列表请求,会产生无效的接口调用
实现方案
该需求完全可以实现,基于React的状态管理机制实现即可:
- 在组件中定义state用来存储拉取到的列表数据
- 在组件生命周期钩子(类组件用
componentDidMount/componentDidUpdate,函数组件用useEffect)中调用异步方法拉取数据 - 数据拉取完成后更新state,将state中存储的数组传给
DetailsList的items属性
完整代码示例
1. 修正异步请求方法
public async getTabData(theList = "ListOfLinks"): Promise<any[]> { console.log('getTabData'); const web = Web(this.props.webURL); // 移除多余的无效请求行 const items: any[] = await web.lists.getByTitle(theList).items.select(...colsToSelect).get(); console.log('items:', items); // 补充return返回获取到的数组 return items; }
2. 定义组件state
// 组件state接口定义(替换为你实际的组件名前缀) export interface IYourSpfxComponentState { listItems: any[]; isLoading: boolean; } // 组件类中初始化state public state: IYourSpfxComponentState = { listItems: [], isLoading: false };
3. 生命周期中调用异步方法更新state
// 组件挂载完成后加载数据 public componentDidMount(): void { this.loadListData(item.ListToShow); } // 如果列表名会动态变化,新增更新判断逻辑 public componentDidUpdate(prevProps: IYourSpfxComponentProps): void { if (prevProps.item.ListToShow !== this.props.item.ListToShow) { this.loadListData(this.props.item.ListToShow); } } // 封装数据加载逻辑 private async loadListData(listName: string): Promise<void> { this.setState({ isLoading: true }); try { const items = await this.getTabData(listName); this.setState({ listItems: items, isLoading: false }); } catch (error) { console.error('SPO列表数据拉取失败:', error); this.setState({ listItems: [], isLoading: false }); } }
4. 修正DetailsList调用写法
{/* 可根据isLoading状态自行补充加载中提示 */} <DetailsList items={this.state.listItems} {/* 其余原有属性保持不变 */} />
注意事项
- 不要在JSX属性中直接调用异步方法,JSX渲染是同步执行的,无法获取到Promise resolve后的值
- 建议将代码中的
any替换为你实际的列表项结构类型,增强类型安全性,避免后续类型报错
内容的提问来源于stack exchange,提问作者Pete Whelan
相关产品推荐
相关产品推荐

