如何禁用react-admin的optimistic rendering缓存并解决计算字段为空问题?
解决react-admin详情页计算字段为空的问题
当react-admin从列表页导航到详情页时会复用列表缓存的记录,若仅在getOne接口返回计算字段,就会出现详情页这些字段为空的情况,以下是几种可行的解决方法:
1. 自定义数据提供者合并缓存与新字段
修改getOne方法,先获取列表缓存中的记录,再与getOne返回的带计算字段的数据合并,确保既保留列表已加载的数据,又补上新增的计算字段。
示例代码:
// 假设你已经有原始的dataProvider const enhancedDataProvider = { ...originalDataProvider, async getOne(resource, params) { // 调用原始getOne获取带计算字段的数据 const { data: newData, ...rest } = await originalDataProvider.getOne(resource, params); // 通过react-query的queryClient获取列表缓存 const queryClient = getQueryClient(); const cachedListData = queryClient.getQueryData([resource, 'list']); if (cachedListData) { // 找到缓存中对应的记录 const cachedRecord = cachedListData.data.find(item => item.id === params.id); if (cachedRecord) { // 合并缓存数据与新数据,优先保留getOne返回的字段 const mergedData = { ...cachedRecord, ...newData }; return { ...rest, data: mergedData }; } } // 无缓存则直接返回原始getOne结果 return { ...rest, data: newData }; } };
2. 强制详情页重新获取数据
给详情页的useGetOne钩子配置参数,禁用缓存复用,强制每次进入详情页都发起新请求获取完整数据。
示例代码:
import { useGetOne } from 'react-admin'; const PostShow = ({ id }) => { // 设置staleTime为0,强制每次挂载都重新获取数据 const { data: post, isLoading } = useGetOne('posts', { id, options: { staleTime: 0, refetchOnMount: true } }); if (isLoading) return <div>加载中...</div>; return ( <div> <h1>{post.title}</h1> {/* 渲染计算字段 */} <p>计算值: {post.calculatedField}</p> </div> ); };
3. 手动更新列表缓存
在详情页获取到getOne的数据后,手动更新列表缓存中对应记录的字段,这样后续跳转时缓存就包含完整数据了。
示例代码:
import { useGetOne, useQueryClient } from 'react-admin'; import React from 'react'; const PostShow = ({ id }) => { const queryClient = useQueryClient(); const { data: post } = useGetOne('posts', { id }); React.useEffect(() => { if (!post) return; // 更新列表缓存中的对应记录 queryClient.setQueryData(['posts', 'list'], (oldListData) => { if (!oldListData) return oldListData; return { ...oldListData, data: oldListData.data.map(item => item.id === post.id ? { ...item, ...post } : item ) }; }); }, [post, queryClient]); // 渲染详情内容... };
4. 列表页预加载轻量计算字段
如果部分计算字段的加载成本不高,可以在getList接口中返回这些字段,这样列表缓存中就包含所需数据,详情页复用缓存时不会出现为空的情况。这种方法适合计算逻辑简单、性能影响小的场景。
内容的提问来源于stack exchange,提问作者Orlando
相关产品推荐
相关产品推荐

