React组件等待props传入未重新渲染,一直显示Loading如何解决
问题原因
- useEffect依赖数组为空,只会在组件首次挂载时执行一次。如果此时props.id还未加载完成(比如是undefined/空值),会发送错误请求,且后续props.id更新后也不会重新触发请求
- 初始state的默认值设置错误:你给data的初始值是
[](数组),数组本身没有book属性,所以!data.book判断永远为真,会一直停在Loading状态 - 未添加请求异常捕获逻辑,接口报错/网络错误时不会更新状态,也会导致Loading一直展示
修复方案
- 给useEffect添加
props.id作为依赖,确保props.id更新后会重新发起请求 - 将data的初始值改为
{}(空对象),和接口返回的结构对齐 - 添加catch捕获请求错误,避免异常导致状态卡死
- 渲染列表时增加数组类型判断、添加key属性,避免运行时报错
修正后的完整代码如下:
const Comp = (props) => { // 初始值改为空对象,和接口返回结构对齐,可定义更精准的类型替代any const [data,setData] = useState<any>({}); // 新增加载错误状态做异常提示 const [loadError, setLoadError] = useState(false); console.log(props.id); useEffect(()=>{ // 边界判断:id存在时再发请求,避免无效请求 if (!props.id) return; fetch('url'+props.id,{ method: 'GET', headers: {'Content-Type': 'application/json'}, credentials: 'include', }) .then(function(response){ console.log(response) return response.json(); }).then(function(myJson) { console.log(myJson); setData(myJson) setLoadError(false) }) // 捕获请求异常 .catch(err => { console.error('接口请求失败', err) setLoadError(true) }) // 把props.id加入依赖数组 },[props.id]) // 优先处理错误状态 if (loadError) return <span>加载失败,请刷新重试</span> if (!data.book) { return <span>Loading...</span>; }; return( <div> <ul> {/* 加数组类型判断,同时给列表项添加key属性 */} {Array.isArray(data.book) && data.book.map(item => <li key={item.id}>{item.title}</li>)} </ul> </div> ); }; export default Comp;
内容的提问来源于stack exchange,提问作者CuriousPeet
相关产品推荐
相关产品推荐

