重构adminAPI以包含通用端点
在adminAPI中添加一个动态端点以动态选择资源。
fetchResource端点根据调用期间传入的resourceType动态构建查询URL。
useLazyFetchResourceQuery挂钩用于在单击按钮时手动触发查询。
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
export const adminAPI = createApi({
reducerPath: 'dashboardApi',
baseQuery: fetchBaseQuery({
baseUrl: 'https://jsonplaceholder.typicode.com',
}),
endpoints: (builder) => ({
fetchResource: builder.query({
query: ({ resourceType, params }) => {
// Add query parameters dynamically
const queryParams = params
? '?' +
Object.entries(params)
.map(([key, value]) => `${key}=${value}`)
.join('&')
: '';
return `/${resourceType}${queryParams}`;
},
}),
}),
});
export const { useLazyFetchResourceQuery } = adminAPI;
将当前的多个钩子替换为单个动态查询,并包含基于resourceType及其相关查询参数处理独特功能的逻辑。
import './App.css';
import React, { useState } from 'react';
import { useLazyFetchResourceQuery } from './service';
function App() {
const [resourceType, setResourceType] = useState(null);
const [queryParams, setQueryParams] = useState(null);
const [fetchResource, { data, isFetching, isError }] = useLazyFetchResourceQuery();
const handleFetchResource = (type) => {
setResourceType(type);
// Customize parameters or behavior for each resource
switch (type) {
case 'posts':
setQueryParams({ _limit: 10, _page: 1 });
break;
case 'comments':
setQueryParams({ _limit: 20 });
break;
case 'albums':
setQueryParams(null);
break;
case 'photos':
setQueryParams({ _limit: 5 });
break;
case 'todos':
setQueryParams(null);
break;
case 'users':
setQueryParams(null);
break;
default:
setQueryParams(null);
}
// Trigger the dynamic query with both resource type and its specific params
fetchResource({ resourceType: type, params: queryParams });
};
return (
<>
<button onClick={() => handleFetchResource('posts')}>Load Posts</button>
<button onClick={() => handleFetchResource('comments')}>Load Comments</button>
<button onClick={() => handleFetchResource('albums')}>Load Albums</button>
<button onClick={() => handleFetchResource('photos')}>Load Photos</button>
<button onClick={() => handleFetchResource('todos')}>Load Todos</button>
<button onClick={() => handleFetchResource('users')}>Load Users</button>
<br />
{/* Show loading state */}
{isFetching && <p>Loading {resourceType}...</p>}
{/* Handle error state */}
{isError && <p style={{ color: 'red' }}>Error loading {resourceType} data.</p>}
{/* Show data dynamically with resource-specific logic */}
{data && (
<div>
<h3>{resourceType.charAt(0).toUpperCase() + resourceType.slice(1)}</h3>
<ul>
{/* Customize how to show data based on the resource */}
{Array.isArray(data) &&
data.map((item, index) => {
switch (resourceType) {
case 'posts':
return <li key={index}><strong>{item.title}</strong> - {item.body}</li>;
case 'comments':
return <li key={index}>"{item.body}" by User {item.email}</li>;
case 'albums':
return <li key={index}>{item.title}</li>;
case 'photos':
return <li key={index}><img src={item.thumbnailUrl} alt={item.title} /> {item.title}</li>;
case 'todos':
return <li key={index}>{item.title} - {item.completed ? 'â
' : 'â'}</li>;
case 'users':
return (
<li key={index}>
{item.name} - {item.email}
</li>
);
}
})}
</ul>
</div>
)}
</>
);
}
export default App;
请求会根据点击的按钮动态触发。
任何正在进行的请求都会自动取消,并通过内置的AbortController替换为新的请求。