Next.js组件状态未更新:新增产品后数据不渲染问题
问题原因及解决方案
核心问题1:异步请求顺序错误
你在onSubmit里调用refetchQueries的时机不对——fetch是异步操作,但你没有等待它完成就立即执行了重新查询,这时候后端还没完成产品新增,refetchQueries拿到的自然还是旧数据。
核心问题2:多余的本地状态导致响应式断裂
AdminRightPanel里用productItems这个本地useState中转products数据完全没必要。React Query返回的data本身就是响应式的,多一层本地状态会拉长数据更新链路,甚至可能因为引用比较逻辑导致更新不触发。
具体修复步骤
1. 修正异步请求顺序
把fetch改成await方式,确保POST请求完成后再执行重新查询:
async function onSubmit() { if (base64Image && category) { const product: Product = { id: 0, base64image: base64Image, category: category, }; try { const response = await fetch(`${CUSTOM_URL}api/content/products`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(product), }); if (response.ok) { toast({ title: "数据已更新!", description: "更改即将生效!", }); setBase64Image(null); // 确保POST完成后再重新查询 await queryClient.refetchQueries({ queryKey: ["products"] }); } else { toast({ title: "错误!", description: "出现错误,请稍后重试!", }); } } catch (error) { toast({ title: "错误!", description: "出现错误,请稍后重试!", }); } } }
2. 移除多余的本地状态
在AdminRightPanel里直接把useQuery返回的products传给CatalogEditor,删掉冗余的本地状态代码:
// 删掉以下两行冗余代码 // const [productItems, setProductItems] = useState<Product[]>([]); // useEffect(() => { if (products) setProductItems(products); }, [products]); // 直接传递useQuery的原始数据 case "catalog": return <CatalogEditor products={products} />;
可选优化:直接更新缓存(无需重新请求)
如果不想发起重复请求,可以在POST成功后直接把新产品添加到React Query缓存中,性能更优:
// POST成功后执行 const newProduct = await response.json(); // 假设后端返回新增的产品数据 await queryClient.setQueryData<Product[]>(["products"], (oldData) => { if (!oldData) return [newProduct]; return [...oldData, newProduct]; });
内容的提问来源于stack exchange,提问作者Артем Лебідь
相关产品推荐
相关产品推荐

