React中事件触发后如何正确重新发起API请求?
解决方案
1. 抽离API请求为独立函数
把原本写在useEffect里的axios请求抽成单独的可复用函数,这样不管是初始化加载还是事件触发刷新,都能直接调用它更新数据:
const fetchOps = () => { axios.get("http://cpawautojava:1400/consultaOrdenesPago") .then(response => { setOps(response.data); console.log(response.data); }) .catch(error => console.log(error)); };
2. 初始化时加载数据
在useEffect里调用一次这个函数,保证应用启动时自动加载初始数据:
useEffect(() => { fetchOps(); }, []); // 空依赖数组确保只在组件挂载时执行一次
3. 传递刷新函数给子组件
把fetchOps作为props传给需要触发刷新的OrdenPago和Grid组件,让它们能在按钮点击、表单提交等事件中调用:
// App组件return部分修改 <OrdenPago onRefresh={fetchOps} /> // ... <Grid ops={ops} onRefresh={fetchOps} />
4. 在子组件中触发刷新
以OrdenPago为例,在事件回调中调用props传入的刷新函数:
// OrdenPago组件示例 export const OrdenPago = ({ onRefresh }) => { const handleSubmit = (e) => { e.preventDefault(); // 执行表单提交逻辑 // 提交完成后触发数据刷新 onRefresh(); }; return ( <form onSubmit={handleSubmit}> {/* 表单内容 */} <button type="submit">提交并刷新</button> {/* 单独的刷新按钮 */} <button type="button" onClick={onRefresh}>刷新数据</button> </form> ); };
关于之前的问题说明
window.location.reload是强制刷新整个页面,会丢失React状态,完全没必要,属于不规范的做法。- 直接调用fetch类函数是完全合理的,这是React中更新数据的常规方式,比页面刷新高效得多。
- 之前调整
useEffect依赖项出现无限循环,大概率是因为未缓存函数引用。如果需要把fetchOps放进依赖数组,可以用useCallback包裹来缓存函数:
import { useState, useEffect, useCallback } from 'react'; // ... const fetchOps = useCallback(() => { axios.get("http://cpawautojava:1400/consultaOrdenesPago") .then(response => { setOps(response.data); console.log(response.data); }) .catch(error => console.log(error)); }, []); // 空依赖确保函数只创建一次 useEffect(() => { fetchOps(); }, [fetchOps]); // 现在可安全放入依赖数组
修改后的完整App代码
import { useState, useEffect } from 'react'; import { OrdenPago } from './OrdenDePago'; import EstadoCvus from './EstadoCvus'; import Grid from './Grid'; import axios from 'axios'; export const App = () => { const [ops, setOps] = useState({ ordenesPago: [] }); const fetchOps = () => { axios.get("http://cpawautojava:1400/consultaOrdenesPago") .then(response => { setOps(response.data); console.log(response.data); }) .catch(error => console.log(error)); }; useEffect(() => { fetchOps(); }, []); return ( <div className="container"> <div className='row'> <div className='col-12'> <div className='text-white py-2' style={{ backgroundColor: "#414BB2", height: "40px" }} > <h1 className='text-center lead fw-bold'>Gestión de OPs</h1> </div> </div> </div> <div className='row mt-3' > <div className='col-6 d-flex justify-content-center'> <OrdenPago onRefresh={fetchOps} /> </div> <div className='col-6 form1' > <EstadoCvus /> </div> </div> <div className='row'> <div className='col-12' > <Grid ops={ops} onRefresh={fetchOps} /> </div> </div> </div> ); }
内容的提问来源于stack exchange,提问作者REA1990
相关产品推荐
相关产品推荐

