MERN栈项目加载/重渲染报appointments.map is not a function错误排查
报错原因排查
.map() is not a function报错的核心原因是存在某个时刻,appointments的值不是数组类型,你现有的判断逻辑没有覆盖该场景:
- Redux中
usersReducer的appointment初始值大概率不是空数组,可能是null/undefined/空对象。首次加载时接口请求还未返回,此时appointments非数组,appointments?.length结果为undefined,undefined === 0判断为假,会直接渲染子组件,把非数组值传入触发map报错;刷新后接口已返回数组,所以功能正常。 - 点击确认按钮触发更新时,
confirmAppointment对应的reducer逻辑存在错误:更新appointment字段时没有返回过滤后的数组,反而返回了单个对象或其他非数组类型,重渲染时同样触发map报错;刷新后重新拉取接口拿到正确数组,所以预约条目正常消失。
修复方案
1. 给appointments加数组兜底
确保无论reducer初始值、接口返回值是什么,最终拿到的appointments永远是数组,修改父组件中useSelector代码:
const appointments = useSelector((state)=>state?.usersReducer?.appointment) || []
2. 修正父组件渲染判断逻辑
增加数组类型校验,覆盖非数组的边界场景,修改父组件中的三元判断:
{!Array.isArray(appointments) || appointments.length === 0 ? ( <div>Loading ...</div> ) : ( <ConfirmAppointment user={user} appointments={appointments} /> )}
3. 修正useEffect依赖项
你当前的useEffect用到了user的id,但依赖项只有dispatch,若user异步加载晚于组件首次渲染,会导致第一次请求参数为undefined,可能返回非数组的报错结果,修改为:
useEffect(() => { // 新增判断避免user未加载时发送无效请求 if(user?.result?._id) { dispatch(getAppointments(user.result._id)) } }, [dispatch, user?.result?._id])
4. 校验Redux reducer更新逻辑
分别检查getAppointments、confirmAppointment两个action对应的reducer分支:
getAppointments请求成功时,必须给state.appointment赋值为数组类型confirmAppointment请求成功时,必须返回过滤后的新数组(示例:state.appointment.filter(item => item._id !== 已确认的预约id)),不能直接返回操作后的单个预约对象
内容的提问来源于stack exchange,提问作者Cip
相关产品推荐
相关产品推荐

