Home > database >  Error: MUI: The data grid component requires all rows to have a unique `id` property
Error: MUI: The data grid component requires all rows to have a unique `id` property

Time:04-21

So I am trying to populate a Datagrid using data from my API:

    const [listofInvoices, setListofInvoices] = useState({id: 0})
useEffect(()=>{
    axios.get("http://localhost:3001/invoices").then((response)=>{
        setListofInvoices(response.data) //State which contains the response from the API request
    });
  }, [])
 const rows: GridRowsProp = [listofInvoices];
 const columns: GridColDef[] = [
    { field: "invNumber", headerName: "Invoice Number", width: 150 },
    { field: "invAmount", headerName: "Invoice Amount", width: 150 }
  ];

Then I display the DataGrid using this code:

    <div style={{margin:'auto', height: 450, width: '95%' }}>
  <DataGrid rows={rows} columns={columns} getRowId={(row) => row.id} components={{ Toolbar: GridToolbar }} />
</div>

But I keep getting this error even though all my rows have an id: Console Error

CodePudding user response:

I suspect you're mixing up arrays and objects. Here you initialize the "list of invoices" to a single object (not a list):

const [listofInvoices, setListofInvoices] = useState({id: 0})

To compensate for the fact that it's not an array, you make an array out of it:

const rows: GridRowsProp = [listofInvoices];

And then pass that resulting array to the component. Which works. However, after the AJAX operation you update the state:

setListofInvoices(response.data)

Is response.data just another object, or is it an array (as implied by the URL "invoices")? If it's an array then you're still compensating for it not being an array:

const rows: GridRowsProp = [listofInvoices];

Which means now you're passing the component an array with one element, and that element is also an array, and arrays have no id property.


Start by fixing the semantic problem. Keep singular things singular and plural things plural. Otherwise you're just setting yourself up for confusion. Make the "list of invoices" an actual list:

const [listofInvoices, setListofInvoices] = useState([{id: 0}])

Then you don't have to compensate for it not being an array:

const rows: GridRowsProp = listofInvoices;

And any time you update the state, as long as the "list of invoices" is still an array then it's still semantically plural and still correct. This way what you always have is an array, rather than sometimes an object, sometimes an array, sometimes an array of arrays.

  • Related