Update to SWR version 2.x (#296)

* Update SWR to version 2.1.5

* Improve generic type names

* Use "isLoading" property of "useSWR" response

* Correctly load library without selected tab

With the latest SWR version the library was empty on the first load.
Not sure what exactly is the reason, but due to "isPaused" the request wasn't sent even after "activeTab" wasn't undefined anymore.
Instead of using "isPaused", passing "null" as the key will also prevent SWR from doing the request.
This commit is contained in:
schroda
2023-05-15 11:56:55 +02:00
committed by GitHub
parent 4aff22079a
commit 8dae72604f
11 changed files with 34 additions and 35 deletions

View File

@@ -46,7 +46,7 @@
"react-router-dom": "^5.2.0",
"react-scripts": "^5.0.1",
"react-virtuoso": "^1.8.6",
"swr": "^1.3.0",
"swr": "^2.1.5",
"use-query-params": "^1.2.3",
"web-vitals": "^2.1.0"
},

View File

@@ -87,7 +87,7 @@ const ChapterList: React.FC<IProps> = ({ mangaId }) => {
const {
data: chaptersData,
mutate,
loading,
isLoading,
} = useQuery<IChapter[]>(`/api/v1/manga/${mangaId}/chapters?onlineFetch=false`);
const chapters = useMemo(() => chaptersData ?? [], [chaptersData]);
@@ -176,7 +176,7 @@ const ChapterList: React.FC<IProps> = ({ mangaId }) => {
.catch(() => makeToast(t(actionsStrings[action].error, { count: chapterIds.length }) as string, 'error'));
};
if (loading) {
if (isLoading) {
return (
<div
style={{

View File

@@ -101,7 +101,7 @@ export default function MangaExtensions() {
);
}, [t, shownLangs]);
const { data: allExtensions, mutate, loading } = useQuery<IExtension[]>('/api/v1/extension/list');
const { data: allExtensions, mutate, isLoading } = useQuery<IExtension[]>('/api/v1/extension/list');
const filteredExtensions = useMemo(
() =>
@@ -169,7 +169,7 @@ export default function MangaExtensions() {
};
}, []);
if (loading) {
if (isLoading) {
return <LoadingPlaceholder />;
}

View File

@@ -36,7 +36,7 @@ export default function Library() {
const { options } = useLibraryOptionsContext();
const [lastLibraryUpdate, setLastLibraryUpdate] = useState(Date.now());
const { data: tabsData, error: tabsError, loading } = useQuery<ICategory[]>('/api/v1/category');
const { data: tabsData, error: tabsError, isLoading } = useQuery<ICategory[]>('/api/v1/category');
const tabs = tabsData ?? [];
const librarySize = useMemo(() => tabs.map((tab) => tab.size).reduce((prev, curr) => prev + curr, 0), [tabs]);
@@ -46,10 +46,8 @@ export default function Library() {
const {
data: mangaData,
error: mangaError,
loading: mangaLoading,
} = useQuery<IManga[]>(`/api/v1/category/${activeTab?.id}`, {
isPaused: () => activeTab == null,
});
isLoading: mangaLoading,
} = useQuery<IManga[]>(activeTab ? `/api/v1/category/${activeTab?.id}` : null);
const mangas = mangaData ?? [];
const { setTitle, setAction } = useContext(NavbarContext);
@@ -88,7 +86,7 @@ export default function Library() {
);
}
if (loading) {
if (isLoading) {
return <LoadingPlaceholder />;
}

View File

@@ -34,7 +34,7 @@ const Manga: React.FC = () => {
const {
data: manga,
error,
loading,
isLoading,
isValidating,
mutate,
} = useQuery<IManga>(`/api/v1/manga/${id}/?onlineFetch=false`);
@@ -95,7 +95,7 @@ const Manga: React.FC = () => {
</Stack>
</NavbarToolbar>
{loading && <LoadingPlaceholder />}
{isLoading && <LoadingPlaceholder />}
{manga && <MangaDetails manga={manga} />}
<ChapterList mangaId={id} />

View File

@@ -52,7 +52,7 @@ export default function Sources() {
const [shownLangs, setShownLangs] = useLocalStorage<string[]>('shownSourceLangs', sourceDefualtLangs());
const [showNsfw] = useLocalStorage<boolean>('showNsfw', true);
const { data: sources, loading } = useQuery<ISource[]>('/api/v1/source/list');
const { data: sources, isLoading } = useQuery<ISource[]>('/api/v1/source/list');
const history = useHistory();
@@ -89,7 +89,7 @@ export default function Sources() {
);
}, [t, shownLangs, sources]);
if (loading) return <LoadingPlaceholder />;
if (isLoading) return <LoadingPlaceholder />;
if (sources?.length === 0) {
return <h3>{t('source.error.label.no_sources_found')}</h3>;

View File

@@ -77,13 +77,13 @@ export default function LibrarySettings() {
setAction(null);
}, [t]);
const { data: categories, loading, error: requestError, mutate } = useQuery<ICategory[]>('/api/v1/category/');
const { data: categories, isLoading, error: requestError, mutate } = useQuery<ICategory[]>('/api/v1/category/');
const [currentCategories, setCurrentCategories] = useState<ICategory[]>(categories ?? []); // categories to check if response categories changed
const [dialogCategories, setDialogCategories] = useState<ICategory[]>(categories ?? []); // categories that are shown and updated in the dialog
const [isDialogOpen, setIsDialogOpen] = useState(false);
const retrievedCategoriesChanged = !loading && categories?.length && categories !== currentCategories;
const retrievedCategoriesChanged = !isLoading && categories?.length && categories !== currentCategories;
if (retrievedCategoriesChanged) {
setCurrentCategories(categories);
setDialogCategories(categories);

View File

@@ -46,13 +46,7 @@ export async function fetcher<T = any>(path: string) {
return res.data as T;
}
export const useQuery = <D extends any = any, E extends any = any>(
key: string,
config?: SWRConfiguration<D, E>,
): SWRResponse<D, E> & { loading: boolean } => {
const res = useSWR(key, config);
return {
...res,
loading: res.data == null && res.error == null,
};
};
export const useQuery = <Data extends any = any, Error extends any = any>(
key: string | null,
config?: SWRConfiguration<Data, Error>,
): SWRResponse<Data, Error> => useSWR(key, config);

View File

@@ -45,10 +45,10 @@ export const useDefaultReaderSettings = (): {
settings: IReaderSettings;
loading: boolean;
} => {
const { data: meta, loading } = useQuery<Metadata>('/api/v1/meta');
const { data: meta, isLoading } = useQuery<Metadata>('/api/v1/meta');
const settings = getReaderSettingsWithDefaultValueFallback<IReaderSettings>(meta);
return { metadata: meta, settings, loading };
return { metadata: meta, settings, loading: isLoading };
};
/**

View File

@@ -16,8 +16,8 @@ export const useSearchSettings = (): {
settings: ISearchSettings;
loading: boolean;
} => {
const { data: meta, loading } = useQuery<Metadata>('/api/v1/meta');
const { data: meta, isLoading } = useQuery<Metadata>('/api/v1/meta');
const settings = getSearchSettingsWithDefaultValueFallback(meta);
return { metadata: meta, settings, loading };
return { metadata: meta, settings, loading: isLoading };
};

View File

@@ -10199,10 +10199,12 @@ svgo@^2.7.0:
picocolors "^1.0.0"
stable "^0.1.8"
swr@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/swr/-/swr-1.3.0.tgz#c6531866a35b4db37b38b72c45a63171faf9f4e8"
integrity sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==
swr@^2.1.5:
version "2.1.5"
resolved "https://registry.yarnpkg.com/swr/-/swr-2.1.5.tgz#688effa719c03f6d35c66decbb0f8e79c7190399"
integrity sha512-/OhfZMcEpuz77KavXST5q6XE9nrOBOVcBLWjMT+oAE/kQHyE3PASrevXCtQDZ8aamntOfFkbVJp7Il9tNBQWrw==
dependencies:
use-sync-external-store "^1.2.0"
symbol-tree@^3.2.4:
version "3.2.4"
@@ -10591,6 +10593,11 @@ use-query-params@^1.2.3:
dependencies:
serialize-query-params "^1.3.5"
use-sync-external-store@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"