React Admin中emptyWhileLoading属性报错问题求解
在React Admin开发中,我没有使用默认布局组件,而是自定义了布局。默认布局在数据加载时会返回null,但自定义布局需要自行处理数据未定义的情况,这导致页面加载时出现ReferenceError: data is not defined错误。
为解决这个问题,我尝试给List组件添加emptyWhileLoading属性(该属性会在数据加载完成前不渲染子组件),但添加后出现警告:
React does not recognize the
emptyWhileLoadingprop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercaseemptywhileloadinginstead. If you accidentally passed it from a parent component, remove it from the DOM element.
我已经参照官方文档在List组件中添加了该属性,但问题仍未解决,相关代码如下:
export default props => ( <List emptyWhileLoading pagination={ <Pagination /> } bulkActionButtons={ false } sort={{ field: 'id', order: 'DESC' }} filters={ <ListFilter /> } actions={ <ListActions /> } { ...props } > <Datagrid rowClick="edit"> <TextField source="id" /> <TextField source="name" /> <TextField source="type" /> <TextField source="created_by_username" /> <FunctionField label="Created at" source="created_at" render={ (record, key) => record[key] ? formatDatetime(record[key]) : null } /> <FunctionField label="Updated at" source="updated_at" render={ (record, key) => record[key] ? formatDatetime(record[key]) : null } /> <AudienceActions /> </Datagrid> </List> );
1. 解决ReferenceError: data is not defined核心问题
自定义布局的问题不在List组件,而是你的自定义布局组件在数据加载完成前就尝试访问data了。你需要在自定义布局里主动处理加载状态:
- 在自定义布局组件中,使用
useListContext钩子获取loading状态:import { useListContext } from 'react-admin'; const CustomLayout = ({ children }) => { const { loading } = useListContext(); // 加载状态下返回占位符或null,避免访问未定义的data if (loading) return <div>加载中...</div>; return <div>{children}</div>; };
这样就能在数据加载完成前阻止渲染依赖data的部分,避免报错。
2. 解决emptyWhileLoading警告问题
情况一:React Admin版本过低
emptyWhileLoading属性是在v3.9.0版本才引入的,如果你的版本低于这个,List组件无法识别该属性,会把它传递给底层DOM元素,从而触发警告。解决办法:
- 升级React Admin到支持该属性的版本;
- 或者手动实现加载时不渲染子组件的逻辑:
export default props => { const { loading } = useListContext(); return ( <List pagination={<Pagination />} bulkActionButtons={false} sort={{ field: 'id', order: 'DESC' }} filters={<ListFilter />} actions={<ListActions />} {...props} > {/* 加载完成后再渲染Datagrid */} {!loading && ( <Datagrid rowClick="edit"> <TextField source="id" /> <TextField source="name" /> <TextField source="type" /> <TextField source="created_by_username" /> <FunctionField label="Created at" source="created_at" render={ (record, key) => record[key] ? formatDatetime(record[key]) : null } /> <FunctionField label="Updated at" source="updated_at" render={ (record, key) => record[key] ? formatDatetime(record[key]) : null } /> <AudienceActions /> </Datagrid> )} </List> ); };
情况二:版本正确但仍有警告
如果你的React Admin版本支持该属性,警告可能是因为{...props}的顺序问题,或者props中包含了同名属性导致冲突。解决办法:
- 把
emptyWhileLoading放在{...props}之后,确保它不会被props中的属性覆盖:<List pagination={<Pagination />} bulkActionButtons={false} sort={{ field: 'id', order: 'DESC' }} filters={<ListFilter />} actions={<ListActions />} {...props} emptyWhileLoading // 放在最后,确保优先级最高 > {/* ...子组件 */} </List> - 或者手动解构props,移除可能传递到DOM的无关属性:
export default props => { // 提取需要的属性,避免传递未识别的prop到DOM const { children, ...restProps } = props; return ( <List emptyWhileLoading pagination={<Pagination />} bulkActionButtons={false} sort={{ field: 'id', order: 'DESC' }} filters={<ListFilter />} actions={<ListActions />} {...restProps} > {children} </List> ); };
内容的提问来源于stack exchange,提问作者Olga

