Remix useFetcher首次load()时data为undefined问题求助
问题:Remix useFetcher首次调用load后data为undefined的问题
我尝试使用@remix-run/react中的useFetcher(),在客户端点击按钮时从服务端获取数据,但首次调用load()时fetcher.data始终为undefined。点击按钮两次后,控制台显示首次点击时data为undefined,第二次正常。我曾以为是fetcher.load()异步未完成,但添加async/await无效,请问问题出在哪里?
相关代码
app/routes/api.test.tsx
export const loader = async ({ request }: LoaderFunctionArgs) => { return { data: "test" }; };
app/routes/_index.tsx
export default function Index() { const testFetcher = useFetcher(); const handleClick = () => { testFetcher.load("/api/test"); console.log(testFetcher); }; return ( <div > <button onClick={handleClick}>click</button> </div> ); }
解答
这是因为useFetcher.load()是异步操作,但它不会返回Promise,所以加async/await完全没用。而且React状态更新本身是异步的,你在调用load()后立刻打印testFetcher,此时组件还没重新渲染,自然拿不到最新的data。
核心原因拆解
fetcher.load()触发网络请求后,请求完成才会更新fetcher的状态(包括data),这个更新会触发组件重新渲染,但不会同步修改当前你拿到的testFetcher对象。- 第一次点击时,你打印的是调用
load()前的旧状态,此时请求还在pending,data自然是undefined;第二次点击时,第一次请求已经完成,data已经更新,所以能打印出正确值。
正确处理方式
不要在调用load()后立刻打印,而是通过组件渲染获取最新状态,或者用useEffect监听fetcher.data的变化:
export default function Index() { const testFetcher = useFetcher(); // 监听data变化,获取最新值 useEffect(() => { if (testFetcher.data) { console.log("获取到数据:", testFetcher.data); } }, [testFetcher.data]); const handleClick = () => { testFetcher.load("/api/test"); }; return ( <div > <button onClick={handleClick}>click</button> {/* 直接在JSX中展示最新数据 */} {testFetcher.data && <p>返回数据:{testFetcher.data.data}</p>} {/* 显示请求状态 */} {testFetcher.state === "loading" && <p>加载中...</p>} </div> ); }
内容的提问来源于stack exchange,提问作者Daniel Jung
相关产品推荐
相关产品推荐

