React中如何让异步函数在主函数组件执行前运行并获取路由参数?
解决方案:React组件中获取路由参数后异步请求API并渲染数据
你的问题核心在于依赖全局变量管理状态,且没有在组件生命周期的正确时机触发API请求。React组件中需通过状态钩子管理数据,结合useEffect在路由参数变化时发起请求,确保数据获取与视图渲染同步。
修正后的完整代码
import { useLocation, useEffect, useState } from 'react'; // 建议将API_KEY存入环境变量,避免硬编码 const API_KEY = '你的API_KEY'; function MovieDetails() { const location = useLocation(); // 用useState管理评分数据,初始为空数组 const [ratings, setRatings] = useState([]); // 加载状态,优化用户体验 const [isLoading, setIsLoading] = useState(true); // 错误状态,处理请求失败场景 const [error, setError] = useState(null); // 封装异步请求函数,直接在组件内定义可访问状态钩子 async function fetchMovieRatings(genreId) { setIsLoading(true); setError(null); try { // 动态拼接请求URL,直接使用传入的genreId const url = `https://api.themoviedb.org/3/discover/movie?${API_KEY}&with_genres=${genreId}`; const response = await fetch(url); if (!response.ok) { throw new Error(`请求失败:${response.status}`); } const data = await response.json(); // 用map生成新的评分数组,遵循React不可变状态原则 const newRatings = data.results.map(movie => movie.vote_average); setRatings(newRatings); } catch (err) { setError(err.message); } finally { setIsLoading(false); } } // 使用useEffect监听路由参数变化,触发请求 useEffect(() => { const genreId = location.state?.id; // 确保获取到有效ID后再发起请求 if (genreId) { fetchMovieRatings(genreId); } else { setError('未获取到分类ID'); setIsLoading(false); } }, [location.state?.id]); // 依赖项设为genreId,ID变化时自动重新执行 // 根据状态渲染对应内容 if (isLoading) { return <div>加载中...</div>; } if (error) { return <div>出错了:{error}</div>; } return ( <div> <h3>电影评分列表</h3> <ul> {/* 遍历评分渲染成列表,比直接输出数组更友好 */} {ratings.map((rating, index) => ( <li key={index}>评分:{rating}</li> ))} </ul> </div> ); } export default MovieDetails;
关键修改说明
- 替换全局变量为状态钩子:用
useState管理ratings、加载状态和错误状态,状态变化会自动触发组件重新渲染,保证视图与数据同步。 - 用
useEffect控制请求时机:将路由参数location.state?.id作为依赖项,参数变化时自动发起请求,确保每次路由跳转都能获取对应数据。 - 优化异步函数写法:统一使用
async/await,添加错误捕获逻辑,避免请求失败导致页面崩溃;用map生成新数组更新状态,符合React不可变状态规范。 - 增加状态反馈:通过加载、错误状态提示用户当前请求进度,提升体验。
内容的提问来源于stack exchange,提问作者Moaaz Siddiqui
相关产品推荐
相关产品推荐

