如何优化Jokes组件以避免点击刷新按钮时重复发起API请求?
优化方案:消除重复API请求逻辑
核心思路是把重复的API请求与状态更新逻辑提取为独立函数,同时优化加载状态的管理,让代码更简洁易维护。
优化后的完整代码
import { useState, useEffect } from 'react'; import { useParams } from 'react-router-dom'; import { Container, Card, Button, Spinner } from 'react-bootstrap'; // 假设使用Bootstrap组件 export default function Jokes() { const { cat } = useParams(); const [joke, setJoke] = useState(""); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(false); const api = useApi(); // use context for the api // 提取重复逻辑为独立函数 const fetchJoke = async () => { setIsLoading(true); setError(false); try { const response = await api.getJokes(cat); if (response.ok) { const { body: newJoke } = response; setJoke(newJoke); } else { throw new Error('Failed to fetch joke'); } } catch (err) { setError(true); setJoke(""); } finally { setIsLoading(false); } }; // 页面加载或分类变化时获取笑话 useEffect(() => { fetchJoke(); }, [cat]); // 刷新按钮点击事件直接调用提取的函数 const handleRefresh = () => { fetchJoke(); }; // 加载状态渲染 if (isLoading) { return <Spinner animation="border" />; } // 错误状态渲染 if (error) { return <div>Failed to load joke. Please try again later.</div>; } // 正常状态渲染 return ( <Container> <Card> <Card.Body>{joke}</Card.Body> </Card> <Button style={{ marginTop: "20px" }} onClick={handleRefresh}> Load New </Button> </Container> ); }
关键优化点
- 消除重复逻辑:将原
useEffect和refresh函数中的API请求、响应处理、状态更新逻辑统一到fetchJoke函数中,两处调用只需复用该函数,避免代码冗余。 - 优化状态管理:
- 新增
isLoading状态单独管理加载状态,替代原有的joke.joke === ""判断,逻辑更清晰。 - 新增
error状态处理请求失败场景,避免原代码中setJoke(null)后访问joke.joke导致的空值错误。
- 新增
- 简化渲染逻辑:拆分加载、错误、正常三种状态的渲染分支,避免嵌套条件判断,代码可读性更强。
- 错误处理增强:使用
try/catch捕获异步请求中的异常,确保所有失败场景都能被正确处理。
内容的提问来源于stack exchange,提问作者tharuka89
相关产品推荐
相关产品推荐

