React出现[object Promise]渲染报错 Objects are not valid as a React child如何修复
问题根因
async声明的异步函数默认返回Promise对象,你在lessons.map中直接将getMark的返回值插入JSX节点,React不支持渲染Promise类型,直接触发报错。useEffect中调用异步的getLessons后立刻执行setLoading(false),没有等待请求完成,loading状态失效。- 将JSX节点存入
marks状态不符合React最佳实践,状态应存储原始数据,渲染阶段再组装节点。
修复步骤
- 改造
getAllMarks为异步函数,用Promise.all等待所有分数请求完成后,再将原始分数数据存入marks状态 - 调整
loading状态的更新时机,等所有请求完成后再设为false - 渲染阶段再根据
marks数据生成对应的<th>节点
修改后完整代码
const [marks, setMarks] = useState([]) const [lessons, setLessons] = useState([]) const [loading, setLoading] = useState(true) const getLessons = async(subjectID) => { var res = await fetch("http://localhost:5002/graphql", { method: "post", headers: { "Content-Type": "application/json", Authorization: "Bearer " + localStorage.authToken }, body: JSON.stringify({ query: `query adad { getSubjectLessons(subject:${subjectID}){ id, date }}`, }), }).then(data => data.json()) const lessonList = res.data.getSubjectLessons setLessons(lessonList) // 等待所有分数请求完成后再更新状态 await getAllMarks(lessonList); setLoading(false); console.log(lessonList) } const getMark = async(pupilID, lessonID) => { var res = await fetch("http://localhost:5002/graphql", { method: "post", headers: { "Content-Type": "application/json", Authorization: "Bearer " + localStorage.authToken }, body: JSON.stringify({ query: `query adad { getPupilMarksByLesson(lesson: ${lessonID} , pupil:${pupilID}){ mark } }`, }), }).then(data => data.json()) if (res.data.getPupilMarksByLesson !== null) { console.log(res.data.getPupilMarksByLesson.mark) return res.data.getPupilMarksByLesson.mark } else { // 空值返回占位符,避免渲染null报错 return '-' } } const getAllMarks = async (lessons) => { // 并行发起所有分数请求,等待全部返回 const markList = await Promise.all(lessons.map(el => getMark(p.pupilID, el.id))) setMarks(markList) } useEffect(() => { getLessons(p.subjectID); }, [])
渲染时用法
你在渲染表头的位置直接遍历marks生成节点即可:
// 你的JSX渲染部分 <tr> {marks.map((mark, index) => <th key={index}>{mark}</th>)} </tr>
内容的提问来源于stack exchange,提问作者exxxamply
相关产品推荐
相关产品推荐

