swr
swr copied to clipboard
UseSwr being called twice, i have done everything but fetched is called twice
Bug report
Description / Observed Behavior
with simple next.js project i am suing useSwr in index.js and i saw that console.log(data); just after useSwr is called twice no matter what.
What kind of issues did you encounter with SWR? data is being fetched twice.
Expected Behavior
It should be fetched once only.
How did you expect SWR to behave here? twice calling?
Repro Steps / Code Example
_app.js ` import "../styles/globals.css"; import "antd/dist/antd.css"; import { Layout, Menu, Breadcrumb } from "antd"; import Home from "."; import MainMenu from "./navbars/main-menu"; const { Header, Content, Footer } = Layout; import { QueryClient, QueryClientProvider } from "react-query"; import { ReactQueryDevtools } from "react-query/devtools"; const queryClient = new QueryClient();
function MyApp({ Component, pageProps }) { // return <Component {...pageProps} /> return ( Layout Home Layout ); }
export default MyApp;
index.js
import Head from "next/head";
import Image from "next/image";
import styles from "../styles/Home.module.css";
import useSWR from "swr"; const fetcher = (url) => fetch(url).then((res) => res.json()); export default function Home() { const { data, error } = useSWR("https://reqbin.com/echo/get/json", fetcher);
console.log(data);
return (
Done
`
Screenshot of issue:
Or share your code snippet or a CodeSandbox link is also appreciated!
Additional Context
SWR version. Add any other context about the problem here.
"swr": "^1.3.0"
If you're using React 18 and StrictMode
, it's likely this is the result of intentional React behaviour:
https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state
With Strict Mode starting in React 18, whenever a component mounts in development, React will simulate immediately unmounting and remounting the component
basically useEffect
and friends will run twice, in development mode only.
Hi @Jazzykhan ,
I was able to avoid multiple fetching of the same data with useSWRImmutable
: https://swr.vercel.app/docs/revalidation#disable-automatic-revalidations
Best regards Davide
I meet the same problem and I try this approach as above. I revise the fetch function like useSWRImmutable but it doesn't work.
Yeah same issue as of now, I noticed that my code is being logged twice thus as soon as I use useSWR. Here is my code example.
import useSWR from "swr";
const fetcher = url => fetch(url).then(r => r.json());
export default function Home() {
const { data } = useSWR("https://dog.ceo/api/breeds/image/random", fetcher, {
revalidateIfStale: false,
revalidateOnFocus: false,
revalidateOnReconnect: false
});
console.log("it is being called twice");
return (
<div></div>
);
}
The console log below:
I already removed react strict mode but swr is definitely the issue. Hope we got solution to this problem soon.
I'm having the same issue
I am also facing the same issue , but in options if you give suspense as true it is rendering only once
Example: https://codesandbox.io/s/swr-1952-forked-zqncu5?file=/src/App.js
When using SWR
- Fetcher will only be called once
- Component will render twice (four times in strict mode)
first
data -> undefined
seconddata -> somthing
- see more details in https://swr.vercel.app/docs/advanced/performance
Well guys I solved this problem by doing like this:
// in service
const { data, error, isLoading } = useSWRImmutable(URL, getLocations);
return {
ranking: data,
isLoading,
error
}
// in component
if (!isLoading)
rankingNames = getRankingNames[0].res
I use Vite, and this is my stupid way
import { AxiosRequestConfig } from 'axios';
import { useEffect, useMemo, useRef } from 'react';
// ref: https://vitejs.dev/guide/env-and-mode#node-env-and-modes
const isStrictMode = import.meta.env.MODE !== 'production';
export function useReqCancel(reqConfig: AxiosRequestConfig, cancelableReq: boolean) {
const firstCancel = useRef(true);
const abortController = useMemo(
() => (cancelableReq ? new AbortController() : null),
[cancelableReq]
);
if (abortController) {
reqConfig.signal = abortController.signal;
}
useEffect(() => {
return () => {
if (firstCancel.current && isStrictMode) {
firstCancel.current = false;
return;
}
firstCancel.current = false;
if (cancelableReq) {
abortController?.abort();
}
};
}, [cancelableReq, firstCancel, abortController]);
}
An easier route is to add dedupingInterval: Infinity
to the useSWR
options.