Next.js 13客户端组件POST请求后更新数据的方案咨询
可行方案汇总
方案1:React状态管理 + 手动重新获取数据
在客户端组件里用useState维护数据状态,结合useEffect初始化加载数据,点击按钮完成POST请求后,手动调用getTest刷新数据:
"use client"; import { useState, useEffect } from 'react'; import { cache } from 'react'; const getTest = cache(async (): Promise<Test[]> => { const response = await fetch("http://localhost:3001/api/test"); return await response.json(); }); const postTest = async (newData: Partial<Test>): Promise<Test> => { const response = await fetch("http://localhost:3001/api/test", { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(newData) }); return await response.json(); }; const Input: FC = () => { const [testList, setTestList] = useState<Test[]>([]); // 初始化加载数据 useEffect(() => { const fetchData = async () => { const data = await getTest(); setTestList(data); }; fetchData(); }, []); const handleAdd = async (newData: Partial<Test>) => { // 执行POST请求 const newItem = await postTest(newData); // 重新获取完整列表更新状态(确保数据和服务端一致) const updatedList = await getTest(); setTestList(updatedList); // 也可以直接把新项加到现有列表(更高效,但要保证POST请求返回数据准确) // setTestList(prev => [...prev, newItem]); }; return ( <div> <button onClick={() => handleAdd({ name: 'new item' })}>添加数据</button> {testList.map(item => <div key={item.id}>{item.name}</div>)} </div> ); };
方案2:使用React Query(或SWR)管理异步数据
借助专业的数据请求库自动处理缓存、数据更新和状态同步,这类库内置了重新获取、缓存失效的能力,适合复杂异步场景:
"use client"; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { cache } from 'react'; const getTest = cache(async (): Promise<Test[]> => { const response = await fetch("http://localhost:3001/api/test"); return await response.json(); }); const postTest = async (newData: Partial<Test>): Promise<Test> => { const response = await fetch("http://localhost:3001/api/test", { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(newData) }); return await response.json(); }; const Input: FC = () => { const queryClient = useQueryClient(); // 获取并缓存数据 const { data: testList } = useQuery({ queryKey: ['testList'], queryFn: getTest }); // 定义POST请求的mutation const addTestMutation = useMutation({ mutationFn: postTest, // 请求成功后失效缓存,自动重新获取最新数据 onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['testList'] }); } }); const handleAdd = (newData: Partial<Test>) => { addTestMutation.mutate(newData); }; return ( <div> <button onClick={() => handleAdd({ name: 'new item' })} disabled={addTestMutation.isLoading}> {addTestMutation.isLoading ? '添加中...' : '添加数据'} </button> {testList?.map(item => <div key={item.id}>{item.name}</div>)} </div> ); };
方案3:客户端缓存+状态触发器
利用cache的复用特性,通过状态变量触发组件重新获取缓存数据,避免直接在事件回调中调用use hook:
"use client"; import { useState, useEffect } from 'react'; import { cache } from 'react'; const getTest = cache(async (): Promise<Test[]> => { const response = await fetch("http://localhost:3001/api/test"); return await response.json(); }); const postTest = async (newData: Partial<Test>): Promise<Test> => { const response = await fetch("http://localhost:3001/api/test", { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(newData) }); return await response.json(); }; const Input: FC = () => { const [testList, setTestList] = useState<Test[]>([]); // 用一个状态变量触发重新获取数据 const [refreshFlag, setRefreshFlag] = useState(0); useEffect(() => { const fetchData = async () => { const data = await getTest(); setTestList(data); }; fetchData(); }, [refreshFlag]); const handleAdd = async (newData: Partial<Test>) => { await postTest(newData); // 更新flag触发useEffect重新执行,获取最新缓存数据 setRefreshFlag(prev => prev + 1); }; return ( <div> <button onClick={() => handleAdd({ name: 'new item' })}>添加数据</button> {testList.map(item => <div key={item.id}>{item.name}</div>)} </div> ); };
内容的提问来源于stack exchange,提问作者harunaga
相关产品推荐
相关产品推荐

