2

Receive below errors, when using Datagrid component with custom queries. Below code works with react-admin ver 3.3.1, whereas it doesn't work with ver 3.8.1

TypeError: Cannot read property 'includes' of undefined

Browser's console info: List components must be used inside a <ListContext.Provider>. Relying on props rather than context to get List data and callbacks is deprecated and won't be supported in the next major version of react-admin.

Refer: https://marmelab.com/react-admin/List.html #Tip: You can use the Datagrid component with custom queries:

import keyBy from 'lodash/keyBy'
import { useQuery, Datagrid, TextField, Pagination, Loading } from 'react-admin'

const CustomList = () => {
    const [page, setPage] = useState(1);
    const perPage = 50;
    const { data, total, loading, error } = useQuery({
        type: 'GET_LIST',
        resource: 'posts',
        payload: {
            pagination: { page, perPage },
            sort: { field: 'id', order: 'ASC' },
            filter: {},
        }
    });

    if (loading) {
        return <Loading />
    }
    if (error) {
        return <p>ERROR: {error}</p>
    }
    return (
        <>
            <Datagrid
                data={keyBy(data, 'id')}
                ids={data.map(({ id }) => id)}
                currentSort={{ field: 'id', order: 'ASC' }}
                basePath="/posts" // required only if you set use "rowClick"
                rowClick="edit"
            >
                <TextField source="id" />
                <TextField source="name" />
            </Datagrid>
            <Pagination
                page={page}
                perPage={perPage}
                setPage={setPage}
                total={total}
            />
        </>
    )
} ```

Please help!

2 Answers 2

6

Since react-admin 3.7, <Datagrid> and <Pagination> read data from a ListContext, instead of expecting the data to be injected by props. See for instance the updated <Datagrid> docs at https://marmelab.com/react-admin/List.html#the-datagrid-component.

Your code will work if you wrap it in a <ListContextProvider>:

import React, { useState } from 'react';
import keyBy from 'lodash/keyBy'
import { useQuery, Datagrid, TextField, Pagination, Loading, ListContextProvider } from 'react-admin'

export const CustomList = () => {
    const [page, setPage] = useState(1);
    const perPage = 50;
    const { data, total, loading, error } = useQuery({
        type: 'GET_LIST',
        resource: 'posts',
        payload: {
            pagination: { page, perPage },
            sort: { field: 'id', order: 'ASC' },
            filter: {},
        }
    });

    if (loading) {
        return <Loading />
    }
    if (error) {
        return <p>ERROR: {error}</p>
    }
    return (
        <ListContextProvider value={{
                data: keyBy(data, 'id'),
                ids: data.map(({ id }) => id),
                total,
                page,
                perPage,
                setPage,
                currentSort: { field: 'id', order: 'ASC' },
                basePath: "/posts",
                resource: 'posts',
                selectedIds: []
        }}>
            <Datagrid rowClick="edit">
                <TextField source="id" />
                <TextField source="name" />
            </Datagrid>
            <Pagination />
        </ListContextProvider >
    )
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for this answer, I exactly did as you mentioned but faced an error saying TypeError: Cannot read property 'field' of undefined. it's when it looks for currentSort.field at Datagrid (Datagrid.js:79). any idea how to solve this?
I think I solved my problem. It seems resource and selectedIds are required for this to work!
@François Zaninotto, is there some reason why the documentation hasn't been updated? Almost 2 years later the section "Rendering <Datagrid> With A Custom Query" at the bottom of the page still has incorrect code, and there are no examples of how to do this properly.
I see 2 reasons: 1/ Nobody ever opened an issue about it in the GitHub repository (I just did it: github.com/marmelab/react-admin/issues/7371) 2/ This is an open-source project. If you need something to be changed, the best way to make it happen is to open a pull request.
0

<ReferenceManyField>, as well as other relationship-related components, also implement a ListContext. That means you can use a <Datagrid> of a <Pagination> inside this component.

https://marmelab.com/react-admin/List.html#uselistcontext

Your code should look like this:

import React, { useState } from 'react';
import keyBy from 'lodash/keyBy'
import { useQuery, Datagrid, TextField, Pagination, Loading, ListContextProvider } from 'react-admin'

export const CustomList = () => {
   
    return (
       <ReferenceManyField reference="Your resource for pull the data" target="linked field">
            <Datagrid rowClick="edit">
                <TextField source="id" />
                <TextField source="name" />
            </Datagrid>
        </ReferenceManyField>
    )
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.