React调用TMDB API首次获数据返回undefined,二次访问正常的原因?
React组件首次加载moviedetails.name报undefined问题分析与解决
问题背景
我正在使用TMDB API开发电视剧网站,路由配置如下:
<> <Router> <Navbar/> <Routes> <Route path='/' element={<Home/>}/> <Route path='/signup' element={<Signup/>}/> <Route path='/movieOverview/:id' element={<MovieOverview/>}/> <Route path='*' element={<Error/>}/> </Routes> </Router> </>
其中MovieOverview组件对应动态路由/movieOverview/:id,用户点击剧集时导航到对应路径,组件通过useParams获取ID。
组件代码如下:
export default function MovieOverview(){ const [moviedetails, setMovieDetails] = React.useState() const {id} = useParams() React.useEffect(() => { getData() window.scrollTo(0,0) }, []) const getData = () => { fetch(`https://api.themoviedb.org/3/tv/${id}?api_key=172f725b29bb276f5c4b6e294a988fc5`) .then(res => res.json()) .then(data => setMovieDetails(data)) } return( <div className='overview-1'> <p className='detail'>{moviedetails.name}</p> </div> ) }
问题:首次加载时访问moviedetails.name出现undefined错误,但删除该代码后重新尝试又能正常获取数据,想知道原因并实现直接正常加载。
原因分析
- 初始状态未定义:
moviedetails初始状态是undefined,组件首次渲染时,API请求还在进行中,此时直接访问moviedetails.name相当于读取undefined.name,必然报错。 - 热重载的巧合:删除代码再恢复时,组件重新渲染,此时之前的API请求可能已经完成,
moviedetails已有数据,所以不会报错,但这只是临时现象,不是根本解决办法。
解决方法
1. 初始化空对象作为默认状态
给moviedetails设置初始空对象,避免直接访问undefined的属性:
const [moviedetails, setMovieDetails] = React.useState({})
首次渲染时moviedetails.name会返回undefined,不会抛出错误,数据返回后会自动更新显示。
2. 条件渲染加载状态
在数据加载完成前,渲染加载提示或空内容:
return( <div className='overview-1'> {moviedetails ? <p className='detail'>{moviedetails.name}</p> : <p>加载中...</p>} </div> )
3. 使用可选链操作符
通过?.操作符安全访问嵌套属性,避免报错:
return( <div className='overview-1'> <p className='detail'>{moviedetails?.name}</p> </div> )
如果moviedetails是undefined,表达式会返回undefined,不会触发错误。
4. 补充useEffect依赖数组
当前useEffect依赖为空,若路由参数id变化,组件不会重新触发API请求。建议把id加入依赖:
React.useEffect(() => { getData() window.scrollTo(0,0) }, [id])
这样切换不同剧集时,会自动重新获取对应数据,避免旧数据残留。
内容的提问来源于stack exchange,提问作者Tomiwa
相关产品推荐
相关产品推荐

