Browse Source

feat: migrate from useRequest to react-query (#11665)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
pull/11672/head
afc163 2 months ago
committed by GitHub
parent
commit
002ddde9b6
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 6
      config/config.ts
  2. 1
      package.json
  3. 2
      src/app.tsx
  4. 9
      src/pages/account/center/components/Applications/index.tsx
  5. 9
      src/pages/account/center/components/Articles/index.tsx
  6. 9
      src/pages/account/center/components/Projects/index.tsx
  7. 7
      src/pages/account/center/index.tsx
  8. 7
      src/pages/account/settings/components/base.tsx
  9. 7
      src/pages/dashboard/analysis/index.tsx
  10. 7
      src/pages/dashboard/monitor/index.tsx
  11. 20
      src/pages/dashboard/workplace/index.tsx
  12. 6
      src/pages/form/basic-form/index.tsx
  13. 35
      src/pages/list/basic-list/index.tsx
  14. 9
      src/pages/list/card-list/index.tsx
  15. 19
      src/pages/list/search/applications/index.tsx
  16. 40
      src/pages/list/search/articles/index.tsx
  17. 2
      src/pages/list/search/projects/data.d.ts
  18. 24
      src/pages/list/search/projects/index.tsx
  19. 9
      src/pages/profile/advanced/index.tsx
  20. 7
      src/pages/profile/basic/index.tsx
  21. 16
      src/pages/table-list/components/CreateForm.tsx
  22. 8
      src/pages/table-list/components/UpdateForm.tsx
  23. 7
      src/pages/table-list/index.tsx
  24. 21
      src/pages/user/register/index.tsx

6
config/config.ts

@ -145,6 +145,12 @@ export default defineConfig({
* @doc https://umijs.org/docs/max/request
*/
request: {},
/**
* @name React Query
* @description 使 react-query
* @doc https://umijs.org/docs/max/react-query
*/
reactQuery: {},
/**
* @name
* @description initialState initialState

1
package.json

@ -43,6 +43,7 @@
"@antv/l7": "^2.22.7",
"@antv/l7-react": "^2.4.3",
"@rc-component/util": "^1.9.0",
"@tanstack/react-query": "^5.97.0",
"antd": "^6.2.2",
"antd-style": "^4.1.0",
"clsx": "^2.1.1",

2
src/app.tsx

@ -156,7 +156,7 @@ export const layout: RunTimeLayoutConfig = ({
/**
* @name request
* axios ahooks useRequest
* axios
* @doc https://umijs.org/docs/max/request#配置
*/
export const request: RequestConfig = {

9
src/pages/account/center/components/Applications/index.tsx

@ -4,7 +4,7 @@ import {
EllipsisOutlined,
ShareAltOutlined,
} from '@ant-design/icons';
import { useRequest } from '@umijs/max';
import { useQuery } from '@tanstack/react-query';
import { Avatar, Card, Dropdown, List, Tooltip } from 'antd';
import numeral from 'numeral';
import React from 'react';
@ -59,10 +59,9 @@ const CardInfo: React.FC<{
const Applications: React.FC = () => {
const { styles: stylesApplications } = useStyles();
// 获取tab列表数据
const { data: listData } = useRequest(() => {
return queryFakeList({
count: 30,
});
const { data: listData } = useQuery({
queryKey: ['applications-list', 30],
queryFn: () => queryFakeList({ count: 30 }).then((res) => res.data),
});
return (

9
src/pages/account/center/components/Articles/index.tsx

@ -1,5 +1,5 @@
import { LikeOutlined, MessageFilled, StarTwoTone } from '@ant-design/icons';
import { useRequest } from '@umijs/max';
import { useQuery } from '@tanstack/react-query';
import { List, Tag } from 'antd';
import React from 'react';
import type { ListItemDataType } from '../../data.d';
@ -20,10 +20,9 @@ const Articles: React.FC = () => {
const { styles } = useStyles();
// 获取tab列表数据
const { data: listData } = useRequest(() => {
return queryFakeList({
count: 30,
});
const { data: listData } = useQuery({
queryKey: ['articles-list', 30],
queryFn: () => queryFakeList({ count: 30 }).then((res) => res.data),
});
return (
<List<ListItemDataType>

9
src/pages/account/center/components/Projects/index.tsx

@ -1,4 +1,4 @@
import { useRequest } from '@umijs/max';
import { useQuery } from '@tanstack/react-query';
import { Card, List } from 'antd';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
@ -12,10 +12,9 @@ dayjs.extend(relativeTime);
const Projects: React.FC = () => {
const { styles } = useStyles();
// 获取tab列表数据
const { data: listData } = useRequest(() => {
return queryFakeList({
count: 30,
});
const { data: listData } = useQuery({
queryKey: ['projects-list', 30],
queryFn: () => queryFakeList({ count: 30 }).then((res) => res.data),
});
return (
<List<ListItemDataType>

7
src/pages/account/center/index.tsx

@ -5,7 +5,7 @@ import {
PlusOutlined,
} from '@ant-design/icons';
import { GridContent } from '@ant-design/pro-components';
import { useRequest } from '@umijs/max';
import { useQuery } from '@tanstack/react-query';
import {
Avatar,
Card,
@ -144,8 +144,9 @@ const Center: React.FC = () => {
const [tabKey, setTabKey] = useState<tabKeyType>('articles');
// 获取用户信息
const { data: currentUser, loading } = useRequest(() => {
return queryCurrent();
const { data: currentUser, isLoading: loading } = useQuery({
queryKey: ['current-user'],
queryFn: () => queryCurrent().then((res) => res.data),
});
// 渲染用户信息

7
src/pages/account/settings/components/base.tsx

@ -7,7 +7,7 @@ import {
ProFormText,
ProFormTextArea,
} from '@ant-design/pro-components';
import { useRequest } from '@umijs/max';
import { useQuery } from '@tanstack/react-query';
import { Button, Input, message, Upload } from 'antd';
import React from 'react';
import { queryCity, queryCurrent, queryProvince } from '../service';
@ -30,8 +30,9 @@ const validatorPhone = (
const BaseView: React.FC = () => {
const { styles } = useStyles();
const { data: currentUser, loading } = useRequest(() => {
return queryCurrent();
const { data: currentUser, isLoading: loading } = useQuery({
queryKey: ['current-user'],
queryFn: () => queryCurrent().then((res) => res.data),
});
const getAvatarURL = () => {
if (currentUser) {

7
src/pages/dashboard/analysis/index.tsx

@ -1,6 +1,6 @@
import { EllipsisOutlined } from '@ant-design/icons';
import { GridContent } from '@ant-design/pro-components';
import { useRequest } from '@umijs/max';
import { useQuery } from '@tanstack/react-query';
import { Col, Dropdown, Row } from 'antd';
import type { RangePickerProps } from 'antd/es/date-picker';
import type { Dayjs } from 'dayjs';
@ -31,7 +31,10 @@ const Analysis: FC<AnalysisProps> = () => {
const [rangePickerValue, setRangePickerValue] = useState<RangePickerValue>(
getTimeDistance('year'),
);
const { loading, data } = useRequest(fakeChartData);
const { isLoading: loading, data } = useQuery({
queryKey: ['dashboard-analysis'],
queryFn: () => fakeChartData().then((res) => res.data),
});
const selectDate = (type: TimeType) => {
setRangePickerValue(getTimeDistance(type));
};

7
src/pages/dashboard/monitor/index.tsx

@ -1,6 +1,6 @@
import { Gauge, Liquid, WordCloud } from '@ant-design/plots';
import { GridContent } from '@ant-design/pro-components';
import { useRequest } from '@umijs/max';
import { useQuery } from '@tanstack/react-query';
import { Card, Col, Progress, Row, Statistic } from 'antd';
import numeral from 'numeral';
import type { FC } from 'react';
@ -13,7 +13,10 @@ const deadline = Date.now() + 1000 * 60 * 60 * 24 * 2 + 1000 * 30; // Moment is
const Monitor: FC = () => {
const { styles } = useStyles();
const { loading, data } = useRequest(queryTags);
const { isLoading: loading, data } = useQuery({
queryKey: ['monitor-tags'],
queryFn: () => queryTags().then((res) => res.data),
});
const wordCloudData = (data?.list || []).map((item) => {
return {
id: +Date.now(),

20
src/pages/dashboard/workplace/index.tsx

@ -1,6 +1,7 @@
import { Radar } from '@ant-design/plots';
import { PageContainer } from '@ant-design/pro-components';
import { Link, useRequest } from '@umijs/max';
import { useQuery } from '@tanstack/react-query';
import { Link } from '@umijs/max';
import { Avatar, Card, Col, List, Row, Skeleton, Statistic } from 'antd';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
@ -90,11 +91,18 @@ const ExtraContent: FC<Record<string, any>> = () => {
};
const Workplace: FC = () => {
const { styles } = useStyles();
const { loading: projectLoading, data: projectNotice = [] } =
useRequest(queryProjectNotice);
const { loading: activitiesLoading, data: activities = [] } =
useRequest(queryActivities);
const { data } = useRequest(fakeChartData);
const { isLoading: projectLoading, data: projectNotice = [] } = useQuery({
queryKey: ['project-notice'],
queryFn: () => queryProjectNotice().then((res) => res.data),
});
const { isLoading: activitiesLoading, data: activities = [] } = useQuery({
queryKey: ['activities'],
queryFn: () => queryActivities().then((res) => res.data),
});
const { data } = useQuery({
queryKey: ['workplace-chart'],
queryFn: () => fakeChartData().then((res) => res.data),
});
const renderActivities = (item: ActivitiesType) => {
const events = item.template.split(/@\{([^{}]*)\}/gi).map((key) => {
if (item[key as keyof ActivitiesType]) {

6
src/pages/form/basic-form/index.tsx

@ -9,7 +9,7 @@ import {
ProFormText,
ProFormTextArea,
} from '@ant-design/pro-components';
import { useRequest } from '@umijs/max';
import { useMutation } from '@tanstack/react-query';
import { Card, message } from 'antd';
import type { FC } from 'react';
import { fakeSubmitForm } from './service';
@ -17,8 +17,8 @@ import useStyles from './style.style';
const BasicForm: FC<Record<string, any>> = () => {
const { styles } = useStyles();
const { run } = useRequest(fakeSubmitForm, {
manual: true,
const { mutate: run } = useMutation({
mutationFn: fakeSubmitForm,
onSuccess: () => {
message.success('提交成功');
},

35
src/pages/list/basic-list/index.tsx

@ -1,6 +1,6 @@
import { DownOutlined, PlusOutlined } from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-components';
import { useRequest } from '@umijs/max';
import { useMutation, useQuery } from '@tanstack/react-query';
import {
Avatar,
Button,
@ -78,17 +78,13 @@ export const BasicList: FC = () => {
const [current, setCurrent] = useState<
Partial<BasicListItemDataType> | undefined
>(undefined);
const {
data: listData,
loading,
mutate,
} = useRequest(() => {
return queryFakeList({
count: 50,
});
const { data: listData, isLoading: loading } = useQuery({
queryKey: ['basic-list'],
queryFn: () => queryFakeList({ count: 50 }).then((res) => res.data),
});
const { run: postRun } = useRequest(
(method, params) => {
const { mutate: postRun } = useMutation({
mutationFn: async ({ method, params }: { method: string; params: any }) => {
if (method === 'remove') {
return removeFakeList(params);
}
@ -97,13 +93,12 @@ export const BasicList: FC = () => {
}
return addFakeList(params);
},
{
manual: true,
onSuccess: (result) => {
mutate(result);
},
},
);
});
// Wrapper to handle the original calling convention
const runListOperation = (method: string, params: any) => {
postRun({ method, params });
};
const list = listData?.list || [];
const paginationProps = {
showSizeChanger: true,
@ -116,7 +111,7 @@ export const BasicList: FC = () => {
setCurrent(item);
};
const deleteItem = (id: string) => {
postRun('remove', {
runListOperation('remove', {
id,
});
};
@ -187,7 +182,7 @@ export const BasicList: FC = () => {
const handleSubmit = (values: BasicListItemDataType) => {
setDone(true);
const method = values?.id ? 'update' : 'add';
postRun(method, values);
runListOperation(method, values);
};
return (
<div>

9
src/pages/list/card-list/index.tsx

@ -1,6 +1,6 @@
import { PlusOutlined } from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-components';
import { useRequest } from '@umijs/max';
import { useQuery } from '@tanstack/react-query';
import { Button, Card, List, Typography } from 'antd';
import type { CardListItemDataType } from './data.d';
import { queryFakeList } from './service';
@ -9,10 +9,9 @@ import useStyles from './style.style';
const { Paragraph } = Typography;
const CardList = () => {
const { styles } = useStyles();
const { data, loading } = useRequest(() => {
return queryFakeList({
count: 8,
});
const { data, isLoading: loading } = useQuery({
queryKey: ['card-list'],
queryFn: () => queryFakeList({ count: 8 }).then((res) => res.data),
});
const list = data?.list || [];
const content = (

19
src/pages/list/search/applications/index.tsx

@ -4,7 +4,7 @@ import {
EllipsisOutlined,
ShareAltOutlined,
} from '@ant-design/icons';
import { useRequest } from '@umijs/max';
import { useQuery } from '@tanstack/react-query';
import {
Avatar,
Card,
@ -79,13 +79,20 @@ const CardInfo: React.FC<{
};
export const Applications: FC<Record<string, any>> = () => {
const { styles } = useStyles();
const { data, loading, run } = useRequest((values: any) => {
console.log('form data', values);
return queryFakeList({
count: 8,
});
const {
data,
isLoading: loading,
refetch,
} = useQuery({
queryKey: ['search-applications'],
queryFn: () => queryFakeList({ count: 8 }).then((res) => res.data),
});
const run = (values: any) => {
console.log('form data', values);
refetch();
};
const list = data?.list || [];
return (

40
src/pages/list/search/articles/index.tsx

@ -4,11 +4,11 @@ import {
MessageOutlined,
StarOutlined,
} from '@ant-design/icons';
import { useRequest } from '@umijs/max';
import { useQuery } from '@tanstack/react-query';
import { Button, Card, Col, Form, List, Row, Select, Tag } from 'antd';
import type { DefaultOptionType } from 'antd/es/select';
import type { FC } from 'react';
import React, { useMemo } from 'react';
import React, { useMemo, useRef } from 'react';
import { categoryOptions } from '../../mock';
import ArticleListContent from './components/ArticleListContent';
import StandardFormRow from './components/StandardFormRow';
@ -54,19 +54,33 @@ const IconText: React.FC<{
const Articles: FC = () => {
const [form] = Form.useForm();
const { styles } = useStyles();
const filtersRef = useRef<{
category?: (string | number)[];
owner?: string[];
}>({});
const { data, reload, loading, loadMore, loadingMore } = useRequest(
() => {
return queryFakeList({
count: pageSize,
});
},
{
loadMore: true,
},
);
const {
data,
isLoading: loading,
isFetching,
refetch,
} = useQuery({
queryKey: ['search-articles', pageSize, filtersRef.current],
queryFn: () =>
queryFakeList({ count: pageSize, ...filtersRef.current }).then(
(res) => res.data,
),
});
const loadMore = () => {
refetch();
};
const loadingMore = isFetching;
const reload = () => {
filtersRef.current = form.getFieldsValue();
refetch();
};
const list = data?.list || [];

2
src/pages/list/search/projects/data.d.ts

@ -6,6 +6,8 @@ export type Member = {
export interface Params {
count: number;
category?: (string | number)[];
author?: string;
}
export interface ListItemDataType {
id: string;

24
src/pages/list/search/projects/index.tsx

@ -1,8 +1,9 @@
import { useRequest } from '@umijs/max';
import { useQuery } from '@tanstack/react-query';
import { Card, Col, Form, List, Row, Select, Typography } from 'antd';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import type { FC } from 'react';
import { useState } from 'react';
import { categoryOptions } from '../../mock';
import AvatarList from './components/AvatarList';
import StandardFormRow from './components/StandardFormRow';
@ -18,12 +19,23 @@ const { Paragraph } = Typography;
const getKey = (id: string, index: number) => `${id}-${index}`;
const Projects: FC = () => {
const { styles } = useStyles();
const { data, loading, run } = useRequest((values: any) => {
console.log('form data', values);
return queryFakeList({
count: 8,
});
const [filters, setFilters] = useState<{
category?: (string | number)[];
author?: string;
}>({});
const {
data,
isLoading: loading,
refetch,
} = useQuery({
queryKey: ['search-projects', filters],
queryFn: () =>
queryFakeList({ count: 8, ...filters }).then((res) => res.data),
});
const run = (values: any) => {
setFilters(values);
};
const list = data?.list || [];
const cardList = list && (
<List<ListItemDataType>

9
src/pages/profile/advanced/index.tsx

@ -9,7 +9,7 @@ import {
PageContainer,
RouteContext,
} from '@ant-design/pro-components';
import { useRequest } from '@umijs/max';
import { useQuery } from '@tanstack/react-query';
import {
Badge,
Button,
@ -271,9 +271,10 @@ const Advanced: FC = () => {
return dot;
};
const { data = {}, loading } = useRequest<{
data: AdvancedProfileData;
}>(queryAdvancedProfile);
const { data = {}, isLoading: loading } = useQuery<AdvancedProfileData>({
queryKey: ['profile-advanced'],
queryFn: () => queryAdvancedProfile().then((res) => res.data),
});
const { advancedOperation1, advancedOperation2, advancedOperation3 } = data;
const contentList = {
tab1: (

7
src/pages/profile/basic/index.tsx

@ -1,6 +1,6 @@
import type { ProColumns } from '@ant-design/pro-components';
import { PageContainer, ProTable } from '@ant-design/pro-components';
import { useRequest } from '@umijs/max';
import { useQuery } from '@tanstack/react-query';
import { Badge, Card, Descriptions, Divider } from 'antd';
import type { FC } from 'react';
import React from 'react';
@ -43,8 +43,9 @@ const progressColumns: ProColumns<BasicProgress>[] = [
];
const Basic: FC = () => {
const { styles } = useStyles();
const { data, loading } = useRequest(() => {
return queryBasicProfile();
const { data, isLoading: loading } = useQuery({
queryKey: ['profile-basic'],
queryFn: () => queryBasicProfile().then((res) => res.data),
});
const { basicGoods, basicProgress } = data || {
basicGoods: [],

16
src/pages/table-list/components/CreateForm.tsx

@ -5,7 +5,8 @@ import {
ProFormText,
ProFormTextArea,
} from '@ant-design/pro-components';
import { FormattedMessage, useIntl, useRequest } from '@umijs/max';
import { useMutation } from '@tanstack/react-query';
import { FormattedMessage, useIntl } from '@umijs/max';
import { Button, message } from 'antd';
import type { FC } from 'react';
import { addRule } from '@/services/ant-design-pro/api';
@ -24,8 +25,8 @@ const CreateForm: FC<CreateFormProps> = (props) => {
* */
const intl = useIntl();
const { run, loading } = useRequest(addRule, {
manual: true,
const { mutateAsync: run, isPending: loading } = useMutation({
mutationFn: addRule,
onSuccess: () => {
messageApi.success('Added successfully');
reload?.();
@ -51,9 +52,12 @@ const CreateForm: FC<CreateFormProps> = (props) => {
width="400px"
modalProps={{ okButtonProps: { loading } }}
onFinish={async (value) => {
await run({ data: value as API.RuleListItem });
return true;
try {
await run({ data: value as API.RuleListItem });
return true;
} catch {
return false;
}
}}
>
<ProFormText

8
src/pages/table-list/components/UpdateForm.tsx

@ -6,7 +6,8 @@ import {
ProFormTextArea,
StepsForm,
} from '@ant-design/pro-components';
import { FormattedMessage, useIntl, useRequest } from '@umijs/max';
import { useMutation } from '@tanstack/react-query';
import { FormattedMessage, useIntl } from '@umijs/max';
import { Modal, message } from 'antd';
import React, { cloneElement, useCallback, useState } from 'react';
import { updateRule } from '@/services/ant-design-pro/api';
@ -34,8 +35,8 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
const [messageApi, contextHolder] = message.useMessage();
const { run } = useRequest(updateRule, {
manual: true,
const { mutateAsync: run } = useMutation({
mutationFn: updateRule,
onSuccess: () => {
messageApi.success('Configuration is successful');
onOk?.();
@ -56,7 +57,6 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
const onFinish = useCallback(
async (values?: any) => {
await run({ data: values });
onCancel();
},
[onCancel, run],

7
src/pages/table-list/index.tsx

@ -9,7 +9,8 @@ import {
ProDescriptions,
ProTable,
} from '@ant-design/pro-components';
import { FormattedMessage, useIntl, useRequest } from '@umijs/max';
import { useMutation } from '@tanstack/react-query';
import { FormattedMessage, useIntl } from '@umijs/max';
import { Button, Drawer, type FormInstance, Input, message } from 'antd';
import React, { useCallback, useRef, useState } from 'react';
import { removeRule, rule } from '@/services/ant-design-pro/api';
@ -31,8 +32,8 @@ const TableList: React.FC = () => {
const [messageApi, contextHolder] = message.useMessage();
const { run: delRun, loading } = useRequest(removeRule, {
manual: true,
const { mutate: delRun, isPending: loading } = useMutation({
mutationFn: removeRule,
onSuccess: () => {
setSelectedRows([]);
actionRef.current?.reloadAndRest?.();

21
src/pages/user/register/index.tsx

@ -1,4 +1,5 @@
import { history, Link, useRequest } from '@umijs/max';
import { useMutation } from '@tanstack/react-query';
import { history, Link } from '@umijs/max';
import {
Button,
Col,
@ -85,15 +86,23 @@ const Register: FC = () => {
}
return 'poor';
};
const { loading: submitting, run: register } = useRequest<{
data: StateType;
}>(fakeRegister, {
manual: true,
const { isPending: submitting, mutate: register } = useMutation({
mutationFn: (formValues: Store) => {
const payload = {
mail: formValues.email,
password: formValues.password,
confirm: formValues.confirm,
mobile: formValues.mobile,
captcha: formValues.captcha,
prefix: formValues.prefix,
};
return fakeRegister(payload);
},
onSuccess: (data, params) => {
if (data.status === 'ok') {
message.success('注册成功!');
history.push({
pathname: `/user/register-result?account=${params[0].email}`,
pathname: `/user/register-result?account=${params.mail}`,
});
}
},

Loading…
Cancel
Save