在反应材料表组件中获取异步数据
Posted
技术标签:
【中文标题】在反应材料表组件中获取异步数据【英文标题】:Getting async data in a react material table component 【发布时间】:2020-09-04 04:09:04 【问题描述】:我正在使用 Firebase 构建一个小型 React 应用程序来托管和存储数据,我正在使用 Material-Table 来显示数据。问题是当我尝试将数据加载到表中时出现此错误:
Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead. in EditTable (at App.js:12) in div (at App.js:10) in App (at src/index.js:10) in StrictMode (at src/index.js:9)
这是表格的代码:
import React from 'react';
import MaterialTable from 'material-table';
import forwardRef from 'react';
import AddBox from '@material-ui/icons/AddBox';
import ArrowDownward from '@material-ui/icons/ArrowDownward';
import Check from '@material-ui/icons/Check';
import ChevronLeft from '@material-ui/icons/ChevronLeft';
import ChevronRight from '@material-ui/icons/ChevronRight';
import Clear from '@material-ui/icons/Clear';
import DeleteOutline from '@material-ui/icons/DeleteOutline';
import Edit from '@material-ui/icons/Edit';
import FilterList from '@material-ui/icons/FilterList';
import FirstPage from '@material-ui/icons/FirstPage';
import LastPage from '@material-ui/icons/LastPage';
import Remove from '@material-ui/icons/Remove';
import SaveAlt from '@material-ui/icons/SaveAlt';
import Search from '@material-ui/icons/Search';
import ViewColumn from '@material-ui/icons/ViewColumn';
import getShotjes from './shotjesDao'
const tableIcons =
Add: forwardRef((props, ref) => <AddBox ...props ref=ref />),
Check: forwardRef((props, ref) => <Check ...props ref=ref />),
Clear: forwardRef((props, ref) => <Clear ...props ref=ref />),
Delete: forwardRef((props, ref) => <DeleteOutline ...props ref=ref />),
DetailPanel: forwardRef((props, ref) => <ChevronRight ...props ref=ref />),
Edit: forwardRef((props, ref) => <Edit ...props ref=ref />),
Export: forwardRef((props, ref) => <SaveAlt ...props ref=ref />),
Filter: forwardRef((props, ref) => <FilterList ...props ref=ref />),
FirstPage: forwardRef((props, ref) => <FirstPage ...props ref=ref />),
LastPage: forwardRef((props, ref) => <LastPage ...props ref=ref />),
NextPage: forwardRef((props, ref) => <ChevronRight ...props ref=ref />),
PreviousPage: forwardRef((props, ref) => <ChevronLeft ...props ref=ref />),
ResetSearch: forwardRef((props, ref) => <Clear ...props ref=ref />),
Search: forwardRef((props, ref) => <Search ...props ref=ref />),
SortArrow: forwardRef((props, ref) => <ArrowDownward ...props ref=ref />),
ThirdStateCheck: forwardRef((props, ref) => <Remove ...props ref=ref />),
ViewColumn: forwardRef((props, ref) => <ViewColumn ...props ref=ref />)
;
export default async function EditTable()
const [state, setState] = React.useState(
columns: [
title: 'ID', field: 'ID' , type: 'numeric' ,
title: 'uitdeler', field: 'Uitdeler' ,
title: 'ontvanger', field: 'Ontvanger' ,
title: 'Uitgedeeld', field: 'Uitgedeeld', lookup: 1: true, 0: false ,,
title: 'datum', field: 'Datum',
,
],
data: getShotjes(),
);
return (
<MaterialTable
title="Editable Example"
columns=state.columns
data=this.state.data
icons=tableIcons
/>
);
这是我的简单 dao 文件减去配置:
import firebase from 'firebase/app'
export async function getShotjes()
try
require("firebase/firestore");
const firebaseConfig =
;
if (!firebase.apps.length)
firebase.initializeApp(firebaseConfig);
var db = firebase.firestore();
const snapshot = await db.collection('shotjes').get();
return snapshot.docs.map(doc => doc.data());
catch (e)
console.log(e);
编辑:
因此,添加一个 useEffect 挂钩并拆分数据和列状态可以消除所有错误。虽然我仍然没有看到表中出现任何数据。我的 Table 组件现在看起来像这样:
export default function EditTable()
var [state, setState] = React.useState(
columns: [
title: 'ID', field: 'id' , type: 'numeric' ,
title: 'Uitdeler', field: 'uitdeler' ,
title: 'Ontvanger', field: 'ontvanger' ,
title: 'Uitgedeeld', field: 'uitgedeeld', lookup: 1: true, 0: false ,,
title: 'Datum', field: 'datum',
,
],
);
var [data, setData] = React.useState([]);
console.log(JSON.stringify(data));
useEffect(() =>
(async () =>
const result = await getShotjes();
console.log(result);
setData(result);
)();
, []);
return (
<MaterialTable
title="Editable Example"
columns=state.columns
data=data.data
icons=tableIcons
/>
);
【问题讨论】:
在useEffect
挂钩中调用getShotjes()
,而不是返回数据,而是使用setData(data)
来设置它(在您的状态下分离列和数据)。
谢谢,我试试
【参考方案1】:
这就是我修复它的方法,我还添加了添加删除数据的功能。
EditTable.js:
export default function EditTable()
var [state, setState] = React.useState(
columns: [
title: 'ID', field: 'id', type: 'numeric', editable: false,
title: 'Uitdeler', field: 'uitdeler' ,
title: 'Ontvanger', field: 'ontvanger' ,
title: 'Datum', field: 'datum', type: 'date',
],
);
var [data, setData] = React.useState([]);
const [isLoading,setIsLoading] = useState(false);
useEffect(() =>
// By moving this function inside the effect, we can clearly see the values it uses.
setIsLoading(true);
async function fetchProduct()
if (!firebase.apps.length)
firebase.initializeApp(firebaseConfig);
setData(await getShotjes());
setIsLoading(false);
fetchProduct();
, []);
const handleCreateShotje = async (shotje) =>
setIsLoading(true);
await addShotje(shotje).then(async () =>
setData(await getShotjes());
);
setIsLoading(false);
;
const handleDeleteShotje = async (id) =>
setIsLoading(true);
await removeShotje(id).then(async () =>
setIsLoading(true);
setTimeout(async function ()
setData(await getShotjes());
, 400);
setIsLoading(false);
);
;
return (
<MaterialTable
title="Shotjes"
columns=state.columns
data=(data)
icons=tableIcons
isLoading=isLoading
editable=
isEditable: rowData => rowData.name === "id", // make id not editable
onRowAdd: (newData) => handleCreateShotje(newData),
onRowDelete: (oldData) => handleDeleteShotje(oldData.id)
/>
);
【讨论】:
以上是关于在反应材料表组件中获取异步数据的主要内容,如果未能解决你的问题,请参考以下文章