React应用刷新后state变为undefined,无法读取image属性问题求助
问题原因
- 你的
useEffect依赖数组为空,只会在组件首次挂载时执行一次逻辑。刷新页面时父组件传递的posts大概率是异步请求获取的,首次渲染时posts还是空数组,过滤Meta分类得到的结果也是空数组,取索引0的值就是undefined,赋值给newestMetaPost后渲染时直接访问image属性就会抛出报错。 - 即使后续
posts异步加载完成,因为useEffect没有把posts加入依赖数组,不会重新执行逻辑更新newestMetaPost,状态一直为undefined。 - 初始状态你给
newestMetaPost设为空数组,和后续要存储的帖子对象类型不匹配,首次渲染时访问数组的image属性本身也会得到不存在的值。 - 组件外部声明的
arrayForHoldingPosts是全局变量,多个组件实例共用会出现数据污染问题。 - 代码中使用
class定义DOM类名不符合React规范,需要替换为className否则类名不会生效。
修复方案
- 给
useEffect添加posts依赖,确保posts更新时重新计算最新的Meta帖子 - 新增边界判断,
newestMetaPost为空时渲染加载占位,或者使用可选链?.避免读取属性报错 - 修正
newestMetaPost初始值为null,新增空数据兜底逻辑 - 将
luxon的导入移到组件顶部,避免每次渲染重复执行require - 把全局的
arrayForHoldingPosts移到组件内部用useRef存储,避免跨实例污染 - 替换所有DOM属性的
class为className
修复后参考代码
import "./Explore.css"; import { DateTime } from "luxon"; import { useState, useEffect, useRef } from "react"; const postsPerLoad = 6; function Explore(props) { const { posts } = props; const [newestMetaPost, setNewestMetaPost] = useState(null); const [allPosts, setAllPosts] = useState([]); const [nextPosts, setNextPosts] = useState(6); const arrayForHoldingPosts = useRef([]); const loopWithSlice = (start, end) => { if (!posts.length) return; const metaPosts = posts.filter(post => post.category === 'Meta'); if (!metaPosts.length) return; const latestMetaPost = metaPosts.sort((b, a) => a.id - b.id)[0]; const filteredMetaPosts = posts.filter(post => post.id !== latestMetaPost.id); const slicedPosts = filteredMetaPosts.reverse().slice(start, end); arrayForHoldingPosts.current = [...arrayForHoldingPosts.current, ...slicedPosts]; setAllPosts(arrayForHoldingPosts.current); }; useEffect(() => { arrayForHoldingPosts.current = []; if (!posts.length) return; const metaPosts = posts.filter(post => post.category === 'Meta'); if (!metaPosts.length) return; const latestMetaPost = metaPosts.sort((b, a) => a.id - b.id)[0]; setNewestMetaPost(latestMetaPost); loopWithSlice(0, postsPerLoad); }, [posts]) const handleShowMorePosts = () => { loopWithSlice(nextPosts, nextPosts + postsPerLoad); setNextPosts(nextPosts + postsPerLoad); }; // 数据未加载完成时显示加载态 if (!newestMetaPost) return <div>加载中...</div> return ( <div > <img className="explore-image" src="https://res.cloudinary.com/tylerwashington98/image/upload/v1636154827/Meta-Minds/meta_vmqfci.jpg" alt="banner image"></img> <div className="latest-and-all-posts-main-div"> <div className="latest-post-div"> <img className="latest-post-image" src={newestMetaPost.image} alt={newestMetaPost.title} ></img> <div className="latest-post-details-div"> <div className="latest-post-details-background-div"></div> <div className="latest-post-details-text-div"> <h4 className="latest-post-details-date-and-category-text-div"> <h6 className="latest-post-details-date text"> {DateTime.now().toLocaleString(DateTime.DATE_MED)}</h6> <img className="meta-logo" src="https://res.cloudinary.com/tylerwashington98/image/upload/v1636143053/Meta-Minds/2d4b6fe46ee740998e2e0f51bbbd3496_esrod4.png" alt="Meta Minds Logo"></img> <h1 className="latest-post-details-category text">{newestMetaPost.category}</h1> </h4> <p className="latest-post-details-title text">{newestMetaPost.title}</p> <p className="latest-post-details-subtitle text subtitle">{newestMetaPost.subtitle}</p> </div> </div> </div> {/* 剩余的帖子列表渲染逻辑 */} </div> </div> ) }
内容的提问来源于stack exchange,提问作者babasuggs
相关产品推荐
相关产品推荐

