Post请求成功后实时刷新GetAssets数据的问题及替代方案咨询
问题概述
我有三个API:GetAssets、assetsOptionsList 和 getAssetsLibrary。需求是向 getAssetsLibrary 发送POST请求提交数据后,GetAssets 接口能实时展示新增的数据。目前功能整体正常,但实时展示有问题:我通过设置 runTime 状态为 true 触发刷新,但这种方式仅首次生效,后续无法实现实时更新。希望找到可行的替代方案,同时要求在POST请求成功时调用获取资产的 one 函数。
现有代码
const [images, setImages] = useState([]); const [assetOptions, setAssetOptions] = useState([]); const [faqOpened, setToggleFaq] = useState(false); const [runTime, setRunTime] = useState(false) const [assetID, setAssetID] = useState() const [isLoading, setIsLoading] = useState(false); const handleForm = (e) => { const index = e.target.selectedIndex; const el = e.target.childNodes[index] const option = el.getAttribute('id'); setAssetID(option) } const formHandler = (e) => { e.preventDefault() let formData = new FormData(); formData.append('media', e.target.media.files[0]); formData.append('assetListId', assetID) formData.append('name', e.target.name.value); console.log(Object.fromEntries(formData)) const res = axios.post('api/asset-library', formData ).then((response) => { showSuccessToaster(response?.data?.message) setRunTime(true) setToggleFaq(false) }) .catch((error) => { showErrorToaster(error?.response?.data?.message) }) } const showSuccessToaster = (response) => { return uploadToasterSuccess.show({ message: response }); } const showErrorToaster = (error) => { return uploadToasterError.show({ message: error }); } const one = async () => { setIsLoading(true) const data = await axios.get('api/assets').then((res) => { return res?.data?.data }) setImages(data) setIsLoading(false) } const two = async () => { const data = await axios.get('/api/asset-list').then((res) => { return res?.data?.data }) setAssetOptions(data) } useEffect(() => { one() two() }, [runTime]);
解决方案
方案1:POST成功后直接调用刷新函数
这是最直接有效的方式,不需要依赖状态触发。在POST请求的成功回调里直接调用one(),因为新增资产后assetOptions(下拉选项列表)通常不会变化,所以可以只刷新资产列表,不用每次都调用two()。
修改后的formHandler代码:
const formHandler = (e) => { e.preventDefault() let formData = new FormData(); formData.append('media', e.target.media.files[0]); formData.append('assetListId', assetID) formData.append('name', e.target.name.value); console.log(Object.fromEntries(formData)) axios.post('api/asset-library', formData) .then((response) => { showSuccessToaster(response?.data?.message) setToggleFaq(false) // 直接调用获取资产的函数,实现实时刷新 one() }) .catch((error) => { showErrorToaster(error?.response?.data?.message) }) }
同时可以删掉冗余的runTime状态和相关依赖,简化初始化逻辑:
// 移除runTime状态 // const [runTime, setRunTime] = useState(false) // 仅在组件挂载时初始化数据 useEffect(() => { one() two() }, []);
方案2:修复原状态触发逻辑(如果一定要用状态驱动)
原方案失效的原因是runTime设为true后,后续再设true不会触发状态变更(因为值没有变化)。可以改成用计数器或者切换布尔值的方式:
// 把runTime换成计数器 const [refreshCount, setRefreshCount] = useState(0) // POST成功时递增计数器,触发状态变更 const formHandler = (e) => { // ... 其他代码 axios.post('api/asset-library', formData) .then((response) => { showSuccessToaster(response?.data?.message) setToggleFaq(false) setRefreshCount(prev => prev + 1) }) // ... 错误处理 } // useEffect依赖refreshCount,每次计数器变化就刷新数据 useEffect(() => { one() two() }, [refreshCount]);
方案3:利用POST返回数据直接更新本地状态
如果getAssetsLibrary接口会返回新增的资产完整数据,可以不用重新调用GetAssets接口,直接把新增数据加到本地images数组里,减少一次网络请求,提升性能:
const formHandler = (e) => { // ... 其他代码 axios.post('api/asset-library', formData) .then((response) => { showSuccessToaster(response?.data?.message) setToggleFaq(false) // 假设response.data.data是新增的资产对象,直接追加到本地列表 setImages(prevImages => [...prevImages, response.data.data]) }) // ... 错误处理 }
内容的提问来源于stack exchange,提问作者David-JSON
相关产品推荐
相关产品推荐

