React中处理Props内Promise异步渲染报错的解决方案
解决React渲染中Promise作为子元素的报错问题
问题根源
你的getBookItem是异步函数,调用后返回的是Promise对象,而React无法直接将Promise作为DOM子元素渲染,因此抛出Objects are not valid as a React child (found: [object Promise])错误。
方案一:提前加载并缓存系统数据(推荐)
既然getSysData的结果是通用字典数据,完全可以在组件初始化时提前加载并缓存,后续渲染时直接同步匹配,避免在render函数里发起异步请求。
修改步骤:
- 在组件内部添加状态存储系统数据
- 组件挂载时预加载数据
- 将
getBookItem改为同步函数,直接使用缓存的数据
import { useState, useEffect } from 'react'; // 组件内部逻辑 const [sysData, setSysData] = useState({}); useEffect(() => { // 组件挂载时加载系统字典数据 const fetchSysData = async () => { const data = await markBook(); setSysData(data); }; fetchSysData(); }, []); // 同步版本的匹配函数 const getBookItem = (key, text) => { if (!sysData[key]) return ''; const targetItem = sysData[key].find(element => element.id === text); return targetItem ? targetItem.value : ''; }; // 表格列配置 { title: 'stage', dataIndex: 'stage', render: (text, record, index) => { return <Tag>{getBookItem(TASK_STAGE, text)}</Tag>; }, }
方案二:封装异步渲染组件
如果必须在渲染时发起请求(不推荐,会导致重复请求),可以封装一个专门处理异步渲染的组件,内部管理加载状态和结果。
自定义异步组件:
import { useState, useEffect } from 'react'; const AsyncTag = ({ keyType, text }) => { const [displayValue, setDisplayValue] = useState(''); useEffect(() => { const fetchTargetValue = async () => { const data = await markBook(); const targetItem = data[keyType].find(element => element.id === text); setDisplayValue(targetItem ? targetItem.value : ''); }; fetchTargetValue(); }, [keyType, text]); return <Tag>{displayValue}</Tag>; }; // 表格列配置 { title: 'stage', dataIndex: 'stage', render: (text, record, index) => { return <AsyncTag keyType={TASK_STAGE} text={text} />; }, }
方案三:使用全局状态管理
如果多个组件都需要用到这套系统字典数据,可以将数据存在全局状态(如Redux、Zustand)中,在应用初始化时加载一次,所有组件直接从全局状态读取同步数据,避免重复请求。
核心思路:
- 在应用入口处加载
markBook数据,存入全局状态 - 组件中从全局状态获取
sysData,同步调用匹配函数
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

