React:关闭Reactstrap模态框时触发TypeError导致应用崩溃问题
问题定位
报错TypeError: Cannot read properties of undefined (reading 'name')的触发原因是关闭模态框的时序和状态更新不同步:
- 关闭模态框时调用
toggleModal没有传入参数,方法内部会同步执行setModalContent(undefined)和setModalOpen(false)两个状态更新 - Reactstrap的Modal自带关闭过渡动画,动画执行过程中组件还未被卸载,此时
modalContent已经被置为undefined,组件渲染时访问modalContent.user.name这类嵌套属性就会抛出错误 - 仅渲染
modalContent.id不报错属于偶发的时序兼容,本质上没有解决属性访问的兜底问题。
解决方法
1. 优化toggleModal的状态更新逻辑
区分打开/关闭模态框的场景,关闭时先修改显隐状态,等动画结束后再清空模态框内容,避免渲染时访问空数据:
const toggleModal = (arg) => { // 传入参数为打开模态框,先设置内容再打开 if (arg) { setModalContent(arg) setModalOpen(true) } else { // 无参数为关闭模态框,先关弹窗,等300ms(对应Modal默认关闭动画时长)再清空内容 setModalOpen(false) setTimeout(() => setModalContent(null), 300) } }
2. 所有嵌套属性访问添加可选链兜底
给FavoritesModal内所有嵌套属性访问添加可选链操作符和默认值,从根源上避免属性不存在的报错:
<ModalHeader> <p> {modalContent.description !== null ? `${modalContent.description ?? '未知图片'} by ${modalContent.user?.name ?? '匿名用户'}` : `Taken by: ${modalContent.user?.name ?? '匿名用户'}`} </p> <p>{modalContent.id}</p> </ModalHeader> <ModalBody> <img src={modalContent.urls?.regular} alt={modalContent.description ?? '图片'} /> </ModalBody> <ModalFooter> <Button color="danger" onClick={() => dispatch(removeFromFavorites(modalContent?.id))} > Remove from favorites </Button> </ModalFooter>
3. (可选)调整组件渲染逻辑
去掉父组件中FavoritesModal的条件渲染,让组件一直挂载,仅通过modalOpen控制显隐,避免组件卸载和动画的时序冲突:
{/* 去掉modalContent的条件判断,直接渲染组件 */} <FavoritesModal modalOpen={modalOpen} modalContent={modalContent} toggleModal={toggleModal} />
FavoritesModal内部已经做了modalContent为空时返回null的判断,不会产生冗余渲染。
内容的提问来源于stack exchange,提问作者bysiuxvx
相关产品推荐
相关产品推荐

