如何在 React Admin 中共享一个 api 对不同资源名称的调用
How to share one api call to different resource names in React Admin
我正在使用 react-admin,我有以下资源:
所以我需要从这里添加一个 Images
和一个 videos
资源。像这样:
因此,正如您在上图中所见,Images
和 Videos
应该 来自同一个端点,称为 Post
.
现在,我在图片中向您展示的内容实际上不起作用。为什么?因为我没有 Image
或 Videos
端点。每次我点击它们时,它都会带我到 http://localhost:3000/dahboard/Images
或 http://localhost:3000/dahboard/Videos
,这又不存在。我的 Posts
端点确实有我需要的内容,它有图像和视频。
我需要什么
我需要的是像我发布的图片那样显示的东西。我可以点击 Images
或 Videos
,无论端点是否直接转到 http://localhost:3000/dahboard/Post
。但是我在react-admin文档中好像找不到相关的东西。
我目前拥有的
<Admin
layout={MyLayout}
theme={theme}
dataProvider={dataProvider}
>
<Resource name="Post" {...posts} icon={ImageIcon} />
<Resource name="Comment" {...comments} icon={ChatIcon} />
<Resource name="User" {...users} icon={PeopleIcon} />
</Admin>
文件夹结构
|-- node_modules
|-- public
|-- src
|---- comments
|---- components
|---- pages
|---- posts
|--- index.js
|--- PostList.js
|--- PostShow.js
|---- users
|--- index.js
|--- UserList.js
|--- UserShow.js
|---- util
|---- videos
|--- index.js
|--- VideoList.js
|--- VideoShow.js
编辑
这就是我配置数据提供程序的方式,为此我使用了 Hasura 的数据提供程序:
function DashboardPage(props) {
const [dataProvider, setDataProvider] = useState(null);
useEffect(() => {
const buildDataProvider = async () => {
const myClientWithAuth = new ApolloClient({
uri: process.env.NEXT_PUBLIC_HASURA_GRAPHQL_ENDPOINT,
cache: new InMemoryCache(),
headers: {
'x-hasura-admin-secret':
process.env.NEXT_PUBLIC_HASURA_GRAPHQL_API_KEY,
},
});
const dataProvider = await buildHasuraProvider({
client: myClientWithAuth,
getList: (resource, params) => {
const {page, perPage} = params.pagination;
const {field, order} = params.sort;
const query = {
sort: JSON.stringify([field, order]),
range: JSON.stringify([(page - 1) * perPage, page * perPage - 1]),
filter: JSON.stringify(params.filter),
};
const endpoint = resource === 'images' || resource === 'videos'
? 'posts'
: resource;
const url = `${apiUrl}/${endpoint}?${stringify(query)}`;
return httpClient(url).then(({ headers, json }) => ({
data: json,
total: parseInt(headers.get('content-range').split('/').pop(), 10),
}));
}
})
setDataProvider(() => dataProvider);
};
buildDataProvider();
}, []);
if (!dataProvider) return <p>Loading...</p>;
return (
<Admin
layout={MyLayout}
theme={theme}
dataProvider={dataProvider}
>
<Resource name="Post" {...posts} icon={ImageIcon} />
<Resource name="Comment" {...comments} icon={ChatIcon} />
<Resource name="User" {...users} icon={PeopleIcon} />
</Admin>
);
放置该逻辑的正确位置是 dataProvider
。您可以将资源名称映射到不同的端点。类似于:
const dataProvider = {
getList: (resource, params) => {
const { page, perPage } = params.pagination;
const { field, order } = params.sort;
const query = {
sort: JSON.stringify([field, order]),
range: JSON.stringify([(page - 1) * perPage, page * perPage - 1]),
filter: JSON.stringify(params.filter),
};
const endpoint = resource === 'images' || resources = 'videos'
? 'posts'
: resource;
const url = `${apiUrl}/${endpoint}?${stringify(query)}`;
return httpClient(url).then(({ headers, json }) => ({
data: json,
total: parseInt(headers.get('content-range').split('/').pop(), 10),
}));
},
// ...
}
我正在使用 react-admin,我有以下资源:
所以我需要从这里添加一个 Images
和一个 videos
资源。像这样:
因此,正如您在上图中所见,Images
和 Videos
应该 来自同一个端点,称为 Post
.
现在,我在图片中向您展示的内容实际上不起作用。为什么?因为我没有 Image
或 Videos
端点。每次我点击它们时,它都会带我到 http://localhost:3000/dahboard/Images
或 http://localhost:3000/dahboard/Videos
,这又不存在。我的 Posts
端点确实有我需要的内容,它有图像和视频。
我需要什么
我需要的是像我发布的图片那样显示的东西。我可以点击 Images
或 Videos
,无论端点是否直接转到 http://localhost:3000/dahboard/Post
。但是我在react-admin文档中好像找不到相关的东西。
我目前拥有的
<Admin
layout={MyLayout}
theme={theme}
dataProvider={dataProvider}
>
<Resource name="Post" {...posts} icon={ImageIcon} />
<Resource name="Comment" {...comments} icon={ChatIcon} />
<Resource name="User" {...users} icon={PeopleIcon} />
</Admin>
文件夹结构
|-- node_modules
|-- public
|-- src
|---- comments
|---- components
|---- pages
|---- posts
|--- index.js
|--- PostList.js
|--- PostShow.js
|---- users
|--- index.js
|--- UserList.js
|--- UserShow.js
|---- util
|---- videos
|--- index.js
|--- VideoList.js
|--- VideoShow.js
编辑
这就是我配置数据提供程序的方式,为此我使用了 Hasura 的数据提供程序:
function DashboardPage(props) {
const [dataProvider, setDataProvider] = useState(null);
useEffect(() => {
const buildDataProvider = async () => {
const myClientWithAuth = new ApolloClient({
uri: process.env.NEXT_PUBLIC_HASURA_GRAPHQL_ENDPOINT,
cache: new InMemoryCache(),
headers: {
'x-hasura-admin-secret':
process.env.NEXT_PUBLIC_HASURA_GRAPHQL_API_KEY,
},
});
const dataProvider = await buildHasuraProvider({
client: myClientWithAuth,
getList: (resource, params) => {
const {page, perPage} = params.pagination;
const {field, order} = params.sort;
const query = {
sort: JSON.stringify([field, order]),
range: JSON.stringify([(page - 1) * perPage, page * perPage - 1]),
filter: JSON.stringify(params.filter),
};
const endpoint = resource === 'images' || resource === 'videos'
? 'posts'
: resource;
const url = `${apiUrl}/${endpoint}?${stringify(query)}`;
return httpClient(url).then(({ headers, json }) => ({
data: json,
total: parseInt(headers.get('content-range').split('/').pop(), 10),
}));
}
})
setDataProvider(() => dataProvider);
};
buildDataProvider();
}, []);
if (!dataProvider) return <p>Loading...</p>;
return (
<Admin
layout={MyLayout}
theme={theme}
dataProvider={dataProvider}
>
<Resource name="Post" {...posts} icon={ImageIcon} />
<Resource name="Comment" {...comments} icon={ChatIcon} />
<Resource name="User" {...users} icon={PeopleIcon} />
</Admin>
);
放置该逻辑的正确位置是 dataProvider
。您可以将资源名称映射到不同的端点。类似于:
const dataProvider = {
getList: (resource, params) => {
const { page, perPage } = params.pagination;
const { field, order } = params.sort;
const query = {
sort: JSON.stringify([field, order]),
range: JSON.stringify([(page - 1) * perPage, page * perPage - 1]),
filter: JSON.stringify(params.filter),
};
const endpoint = resource === 'images' || resources = 'videos'
? 'posts'
: resource;
const url = `${apiUrl}/${endpoint}?${stringify(query)}`;
return httpClient(url).then(({ headers, json }) => ({
data: json,
total: parseInt(headers.get('content-range').split('/').pop(), 10),
}));
},
// ...
}