React.useEffect重渲染不执行:props更新未触发新API调用
问题分析与修复方案
你遇到的这个问题其实很典型——你的useEffect依赖数组是空的[],这意味着这个副作用只会在组件首次挂载时执行一次,之后哪怕props.date更新了,useEffect也不会重新触发,自然不会发起新的API请求。
虽然你在组件顶层更新了searchDate、string_date这些变量,但因为useEffect没有监听这些值的变化,所以完全不会感知到外部props的更新。
修复步骤
补充useEffect的依赖数组
把API调用依赖的string_date(或者直接用props.date)加入到依赖数组中,这样当这个值变化时,useEffect就会重新执行,发起新的请求:添加请求取消逻辑(可选但推荐)
为了避免竞态问题(比如快速切换日期时,旧的API请求晚于新请求返回,导致显示错误数据),可以用AbortController来取消未完成的请求。
修改后的完整代码
export default function News(props) { // 修正你代码里的笔误:原console.log(search_date)应该是console.log(searchDate) const searchDate = moment(props.date, "YYYY-MM-DD HH:mm:ss"); const string_date = searchDate.format("MMMM+DD+YYYY"); const nice_date = searchDate.format("MMMM DD YYYY"); const [search_results, updateSearch] = React.useState([]); console.log(searchDate); React.useEffect(() => { // 创建AbortController实例用于取消请求 const controller = new AbortController(); const signal = controller.signal; googleSearch(string_date, { signal }) // 假设googleSearch支持传入signal参数 .then((response) => { if (!response?.data?.items) { updateSearch([]); } else { updateSearch(response.data.items); } }) .catch((error) => { // 忽略请求被取消的错误 if (error.name !== 'AbortError') { console.error('搜索请求失败:', error); updateSearch([]); } }); // 组件卸载或者依赖变化时,取消未完成的请求 return () => controller.abort(); }, [string_date]); // 加入依赖,string_date变化时重新执行API调用 return ( <React.Fragment> <Button>News For {nice_date}</Button> <GoogleTable data={search_results} date={props.date} /> </React.Fragment> ); }
额外说明
- 如果你的
googleSearch函数本身不支持signal参数,需要稍微改造一下它(以fetch为例):function googleSearch(query, { signal }) { return fetch(`你的搜索API地址?date=${query}`, { signal }) .then(res => res.json()); } - 依赖数组里也可以直接写
[props.date],不过用string_date更精准,能避免props.date格式不变但转换后值不变时,触发不必要的重复请求。
内容的提问来源于stack exchange,提问作者SwimMaster
相关产品推荐
相关产品推荐

