react-admin对接ra-data-graphql-simple报count属性空值读取错误
问题描述
对接ra-data-graphql-simple数据提供程序与自有GraphQL API时,页面底部弹出红色错误提示:
Cannot read properties of null (reading 'count')
Chrome开发者工具Network面板确认接口已返回正确的列表数据,但返回结构中total字段值为null,返回结构参考截图:
涉及代码如下:
Admin入口配置
const App = () => { const [dataProvider, setDataProvider] = React.useState(null); React.useEffect(() => { buildGraphQLProvider({ clientOptions: { uri: 'http://localhost:4000' } }) .then(graphQlDataProvider => setDataProvider(() => graphQlDataProvider)); }, []); if (!dataProvider) return <div>Loading</div> return ( <Admin dataProvider={dataProvider}> <Resource name="FacilityFunction" list={FunctionList} /> </Admin> ); }
列表组件代码
import React from 'react' import { List, Datagrid, TextField, BooleanField } from 'react-admin' export const FunctionList = (props) => { return <List {...props}> <Datagrid> <TextField source="id" /> <TextField source="name" /> <TextField source="code" /> <BooleanField source="isActive" /> </Datagrid> </List> };
依赖版本
"dependencies": { "graphql": "^16.5.0", "ra-data-graphql-simple": "^4.0.3", "react": "18.1", "react-admin": "^4.1.1", "react-dom": "18.1" }
故障原因
ra-data-graphql-simple的列表查询逻辑有固定的返回格式要求:分页接口必须返回非空的总条数字段,内部会读取总条数对象的count属性计算分页参数,用于渲染底部分页控件。当前接口返回的total字段值为null,程序读取count属性时直接触发空引用报错。
解决方案
两种方案二选一即可:
- 优先修改后端接口:对齐
ra-data-graphql-simple的约定返回结构,列表接口返回两个核心字段:items存储当前页的列表数据数组,totalCount存储符合筛选条件的总条目数(数字类型,禁止返回null),不要用total作为总条数字段名。 - 不改动后端的情况下做前端适配:初始化
buildGraphQLProvider时传入自定义解析逻辑,把接口返回的total字段映射到数据提供程序要求的字段位置,同时添加null值兜底逻辑,避免空指针。示例代码:
import buildGraphQLProvider, { defaultParseResponse } from 'ra-data-graphql-simple'; // 替换原有的useEffect内初始化逻辑 React.useEffect(() => { buildGraphQLProvider({ clientOptions: { uri: 'http://localhost:4000' }, introspection: { // 如果后端查询方法名不符合默认命名规则,可在此处自定义映射 operationNames: { getList: (resource) => `all${resource.name}s`, }, parseResponse: (response, resource, operation) => { // 单独处理列表查询的返回解析 if (operation.type === 'getList') { const respData = response.data; return { data: respData.items, // total为null时用当前返回的列表长度兜底,避免报错 total: respData.total?.count ?? respData.items.length } } // 新增、编辑、详情等其他操作走默认解析逻辑 return defaultParseResponse(response, resource, operation); } } }).then(graphQlDataProvider => setDataProvider(() => graphQlDataProvider)); }, []);
内容的提问来源于stack exchange,提问作者stumpykilo
相关产品推荐
相关产品推荐

