Skip to content

Commit

Permalink
♻️ refactor: remove use query (lobehub#5604)
Browse files Browse the repository at this point in the history
* refactor DiscoverTab query

* refactor: refactor use query usage

* clean use query

* fix lint

* wrapper scan
  • Loading branch information
arvinxx authored Jan 27, 2025
1 parent 994568f commit 58c60de
Show file tree
Hide file tree
Showing 19 changed files with 85 additions and 77 deletions.
8 changes: 3 additions & 5 deletions src/app/(main)/discover/features/StoreSearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { memo, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import urlJoin from 'url-join';

import { useQuery } from '@/hooks/useQuery';
import { useQueryRoute } from '@/hooks/useQueryRoute';
import { DiscoverTab } from '@/types/discover';

Expand All @@ -32,9 +31,8 @@ interface StoreSearchBarProps extends SearchBarProps {
const StoreSearchBar = memo<StoreSearchBarProps>(({ mobile, onBlur, onFocus, ...rest }) => {
const [active, setActive] = useState(false);
const pathname = usePathname();
const { q } = useQuery();
const { activeKey } = useNav();
const [searchKey, setSearchKey] = useQueryState('q');
const [searchKey, setSearchKey] = useQueryState('q', { clearOnDefault: true, defaultValue: '' });

const { t } = useTranslation('discover');
const { cx, styles } = useStyles();
Expand All @@ -45,8 +43,8 @@ const StoreSearchBar = memo<StoreSearchBarProps>(({ mobile, onBlur, onFocus, ...
useEffect(() => {
if (!pathname.includes('/discover/search')) return;
// 使用 useQueryState 时,当 handleSearch 为空时无法回跳
if (!q) router.push(urlJoin('/discover', activeType), { query: {}, replace: true });
}, [q, pathname, activeType]);
if (!searchKey) router.push(urlJoin('/discover', activeType), { query: {}, replace: true });
}, [searchKey, pathname, activeType]);

const handleSearch = (value: string) => {
router.push('/discover/search', { query: { q: value, type: activeType } });
Expand Down
6 changes: 3 additions & 3 deletions src/app/(main)/discover/features/useNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ import { useTranslation } from 'react-i18next';
import urlJoin from 'url-join';

import type { MenuProps } from '@/components/Menu';
import { useQuery } from '@/hooks/useQuery';
import { useDiscoverTab } from '@/hooks/useDiscoverTab';
import { DiscoverTab } from '@/types/discover';

export const useNav = () => {
const pathname = usePathname();
const { type } = useQuery();
const type = useDiscoverTab();
const { t } = useTranslation('discover');
const iconSize = { fontSize: 16 };

const activeKey = useMemo(() => {
for (const value of Object.values(DiscoverTab)) {
if (pathname === '/discover/search') {
return (type as DiscoverTab) || DiscoverTab.Assistants;
return type;
} else if (pathname.includes(urlJoin('/discover', value))) {
return value;
}
Expand Down
4 changes: 2 additions & 2 deletions src/app/(main)/discover/search/_layout/Mobile/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { useRouter } from 'next/navigation';
import { memo } from 'react';
import urlJoin from 'url-join';

import { useQuery } from '@/hooks/useQuery';
import { useDiscoverTab } from '@/hooks/useDiscoverTab';
import { mobileHeaderSticky } from '@/styles/mobileHeader';

import StoreSearchBar from '../../../features/StoreSearchBar';

const Header = memo(() => {
const router = useRouter();
const { type = 'assistants' } = useQuery();
const type = useDiscoverTab();

return (
<MobileNavBar
Expand Down
15 changes: 5 additions & 10 deletions src/app/(main)/profile/@category/features/CategoryContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@ import urlJoin from 'url-join';

import Menu from '@/components/Menu';
import { useActiveSettingsKey } from '@/hooks/useActiveTabKey';
import { useQuery } from '@/hooks/useQuery';
import { useQueryRoute } from '@/hooks/useQueryRoute';
import { ProfileTabs, SettingsTabs } from '@/store/global/initialState';
import { ProfileTabs } from '@/store/global/initialState';

import { useCategory } from '../../hooks/useCategory';

const CategoryContent = memo<{ modal?: boolean }>(({ modal }) => {
const CategoryContent = memo(() => {
const activeTab = useActiveSettingsKey();
const { tab = SettingsTabs.Common } = useQuery();
const cateItems = useCategory();
const router = useQueryRoute();

Expand All @@ -22,14 +20,11 @@ const CategoryContent = memo<{ modal?: boolean }>(({ modal }) => {
items={cateItems}
onClick={({ key }) => {
const activeKey = key === ProfileTabs.Profile ? '/' : key;
if (modal) {
router.replace('/profile/modal', { query: { tab: activeKey } });
} else {
router.push(urlJoin('/profile', activeKey));
}

router.push(urlJoin('/profile', activeKey));
}}
selectable
selectedKeys={[modal ? tab : (activeTab as any)]}
selectedKeys={[activeTab]}
variant={'compact'}
/>
);
Expand Down
13 changes: 3 additions & 10 deletions src/app/(main)/settings/@category/features/CategoryContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,23 @@ import urlJoin from 'url-join';

import Menu from '@/components/Menu';
import { useActiveSettingsKey } from '@/hooks/useActiveTabKey';
import { useQuery } from '@/hooks/useQuery';
import { useQueryRoute } from '@/hooks/useQueryRoute';
import { SettingsTabs } from '@/store/global/initialState';

import { useCategory } from '../../hooks/useCategory';

const CategoryContent = memo<{ modal?: boolean }>(({ modal }) => {
const CategoryContent = memo(() => {
const activeTab = useActiveSettingsKey();
const { tab = SettingsTabs.Common } = useQuery();
const cateItems = useCategory();
const router = useQueryRoute();

return (
<Menu
items={cateItems}
onClick={({ key }) => {
if (modal) {
router.replace('/settings/modal', { query: { tab: key } });
} else {
router.push(urlJoin('/settings', key));
}
router.push(urlJoin('/settings', key));
}}
selectable
selectedKeys={[modal ? tab : (activeTab as any)]}
selectedKeys={[activeTab]}
variant={'compact'}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ import { Flexbox } from 'react-layout-kit';

import HeaderContent from '@/app/(main)/chat/settings/features/HeaderContent';
import Menu from '@/components/Menu';
import { useQuery } from '@/hooks/useQuery';
import { useChatSettingsTab } from '@/hooks/useChatSettingsTab';
import { useQueryRoute } from '@/hooks/useQueryRoute';
import { ChatSettingsTabs } from '@/store/global/initialState';

import { useCategory } from './useCategory';

const CategoryContent = memo(() => {
const cateItems = useCategory();
const { tab = ChatSettingsTabs.Meta } = useQuery();
const tab = useChatSettingsTab();
const router = useQueryRoute();

return (
Expand Down
4 changes: 2 additions & 2 deletions src/app/@modal/chat/(.)settings/modal/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useTranslation } from 'react-i18next';
import ModalLayout from '@/app/@modal/_layout/ModalLayout';
import StoreUpdater from '@/features/AgentSetting/StoreUpdater';
import { Provider, createStore } from '@/features/AgentSetting/store';
import { useQuery } from '@/hooks/useQuery';
import { useChatSettingsTab } from '@/hooks/useChatSettingsTab';
import { useAgentStore } from '@/store/agent';
import { agentSelectors } from '@/store/agent/slices/chat';
import { ChatSettingsTabs } from '@/store/global/initialState';
Expand All @@ -24,7 +24,7 @@ const CategoryContent = dynamic(() => import('./features/CategoryContent'), {
});

const Layout = memo<PropsWithChildren>(({ children }) => {
const { tab = ChatSettingsTabs.Meta } = useQuery();
const tab = useChatSettingsTab();
const { t } = useTranslation('setting');
const id = useSessionStore((s) => s.activeId);
const config = useAgentStore(agentSelectors.currentAgentConfig, isEqual);
Expand Down
5 changes: 3 additions & 2 deletions src/app/@modal/chat/(.)settings/modal/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import dynamic from 'next/dynamic';

import { useQuery } from '@/hooks/useQuery';
import { useChatSettingsTab } from '@/hooks/useChatSettingsTab';
import { ChatSettingsTabs } from '@/store/global/initialState';

import Skeleton from './loading';
Expand Down Expand Up @@ -37,7 +37,8 @@ const AgentTTS = dynamic(() => import('@/features/AgentSetting/AgentTTS'), { loa
*/

const Page = () => {
const { tab = ChatSettingsTabs.Meta } = useQuery();
const tab = useChatSettingsTab();

return (
<>
{tab === ChatSettingsTabs.Meta && <AgentMeta />}
Expand Down
8 changes: 8 additions & 0 deletions src/components/withSuspense.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ComponentType, Suspense } from 'react';

// @ts-ignore
export const withSuspense: <T>(Comp: T) => T = (Component: ComponentType<any>) => (props: any) => (
<Suspense>
<Component {...props} />
</Suspense>
);
4 changes: 2 additions & 2 deletions src/features/AgentSetting/AgentTTS/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ const AgentTTS = memo(() => {
return (all?: boolean) => new VoiceList(all ? undefined : locale);
});
const [showAllLocaleVoice, ttsService, updateConfig] = useStore((s) => [
s.config.tts.showAllLocaleVoice,
s.config.tts.ttsService,
s.config.tts?.showAllLocaleVoice,
s.config.tts?.ttsService,
s.setAgentConfig,
]);

Expand Down
6 changes: 3 additions & 3 deletions src/hooks/useActiveTabKey.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { usePathname } from 'next/navigation';
import { useQueryState } from 'nuqs';

import { useQuery } from '@/hooks/useQuery';
import { ProfileTabs, SettingsTabs, SidebarTabKey } from '@/store/global/initialState';

/**
Expand All @@ -17,7 +17,7 @@ export const useActiveTabKey = () => {
*/
export const useActiveSettingsKey = () => {
const pathname = usePathname();
const { tab } = useQuery();
const [tab] = useQueryState('tab');

const tabs = pathname.split('/').at(-1);

Expand All @@ -33,7 +33,7 @@ export const useActiveSettingsKey = () => {
*/
export const useActiveProfileKey = () => {
const pathname = usePathname();
const { tab } = useQuery();
const [tab] = useQueryState('tab');

const tabs = pathname.split('/').at(-1);

Expand Down
12 changes: 12 additions & 0 deletions src/hooks/useChatSettingsTab.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useQueryState } from 'nuqs';

import { ChatSettingsTabs } from '@/store/global/initialState';

export const useChatSettingsTab = () => {
const [type] = useQueryState('tab', {
clearOnDefault: true,
defaultValue: ChatSettingsTabs.Meta,
});

return type as ChatSettingsTabs;
};
12 changes: 12 additions & 0 deletions src/hooks/useDiscoverTab.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useQueryState } from 'nuqs';

import { DiscoverTab } from '@/types/discover';

export const useDiscoverTab = () => {
const [type] = useQueryState('type', {
clearOnDefault: true,
defaultValue: DiscoverTab.Assistants,
});

return type as DiscoverTab;
};
19 changes: 0 additions & 19 deletions src/hooks/useQuery.test.ts

This file was deleted.

8 changes: 0 additions & 8 deletions src/hooks/useQuery.ts

This file was deleted.

10 changes: 6 additions & 4 deletions src/hooks/useQueryRoute.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { renderHook } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';
import { beforeEach, describe, expect, it, vi } from 'vitest';

import { useQueryRoute } from './useQueryRoute';

Expand All @@ -10,13 +10,15 @@ vi.mock('next/navigation', () => ({
replace: vi.fn((href) => href),
})),
}));
vi.mock('@/hooks/useQuery', () => ({
useQuery: vi.fn(() => ({ foo: 'bar' })),
}));

vi.mock('@/utils/env', () => ({
isOnServerSide: false,
}));

beforeEach(() => {
location.search = 'foo=bar';
});

describe('useQueryRoute', () => {
it('should generate correct href without hash and replace', () => {
const { result } = renderHook(() =>
Expand Down
7 changes: 4 additions & 3 deletions src/hooks/useQueryRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { useRouter } from 'next/navigation';
import qs, { type ParsedQuery } from 'query-string';
import { useMemo } from 'react';

import { useQuery } from '@/hooks/useQuery';
import { isOnServerSide } from '@/utils/env';

interface QueryRouteOptions {
Expand Down Expand Up @@ -30,17 +29,19 @@ const genHref = ({ hash, replace, url, prevQuery = {}, query = {} }: GenHrefOpti

export const useQueryRoute = () => {
const router = useRouter();
const prevQuery = useQuery();

return useMemo(
() => ({
push: (url: string, options: QueryRouteOptions = {}) => {
const prevQuery = qs.parse(window.location.search);

return router.push(genHref({ prevQuery, url, ...options }));
},
replace: (url: string, options: QueryRouteOptions = {}) => {
const prevQuery = qs.parse(window.location.search);
return router.replace(genHref({ prevQuery, url, ...options }));
},
}),
[prevQuery],
[],
);
};
12 changes: 12 additions & 0 deletions src/hooks/useSettingsTab.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useQueryState } from 'nuqs';

import { SettingsTabs } from '@/store/global/initialState';

export const useSettingsTab = () => {
const [type] = useQueryState('tab', {
clearOnDefault: true,
defaultValue: SettingsTabs.Common,
});

return type as SettingsTabs;
};
4 changes: 3 additions & 1 deletion src/layout/GlobalProvider/ReactScan.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { useSearchParams } from 'next/navigation';
import Script from 'next/script';
import React, { memo } from 'react';

import { withSuspense } from '@/components/withSuspense';

const ReactScan = memo(() => {
const searchParams = useSearchParams();

Expand All @@ -12,4 +14,4 @@ const ReactScan = memo(() => {
return !!debug && <Script src="https://unpkg.com/react-scan/dist/auto.global.js" />;
});

export default ReactScan;
export default withSuspense(ReactScan);

0 comments on commit 58c60de

Please sign in to comment.