React-Admin: <ReferenceField>застрял в состоянии загрузки, хотя выборка данных завершается успешно - PullRequest
0 голосов
/ 08 апреля 2020

У меня проблема с <ReferenceField>.

На моей странице <List> есть строки с UserId и ToolId, на которые мне нужна ссылка. Я хочу показать user name и tool code.

Но эти два столбца застряли в состоянии загрузки, хотя запрос dataProvider, GET_MANY был успешным для users и tools.

Когда я console.log(data), он все данные есть, но почему-то они не отображаются в <ReferenceField>. И это не ошибка вообще регистрируется.

Есть идеи, что я делаю не так? Или что происходит?

ReferenceFields все еще загружается

РЕДАКТИРОВАТЬ: я обновил реагировать на admin, и теперь он не отображает панель загрузки, но просто ничего не отображать.

Вот код списка:

export const B_toolList = props => (
    <List {...props}>
        <Datagrid rowClick="edit">
            <TextField source="id" />
            <NumberField source="active" />
            <NumberField source="time" />
            <DateField source="createdAt" />
            <DateField source="updatedAt" />
            <ReferenceField source="UserId" reference="Users">
                <TextField source="name" />
            </ReferenceField>
            <ReferenceField source="ToolId" reference="Tools">
                <TextField source="code" />
            </ReferenceField>            
        </Datagrid>
    </List>
);

Я также обнаружил, что если я попытаюсь осмотреть элемент ReferenceField с помощью response-dev-tool, там нет значений, а только примечание «Загрузка ...». Но я не знаю, почему ... Мне кажется, что ответ API в порядке.

API res: выборка Btools:

(2) [{…}, {…}]
0:
ToolId: 1
UserId: 1
active: 1
createdAt: "2020-04-08T16:00:03.000Z"
id: 1
time: 1
updatedAt: "2020-04-08T16:00:03.000Z"
__proto__: Object

1:
ToolId: 1
UserId: 2
active: 1
createdAt: "2020-04-08T16:00:03.000Z"
id: 2
time: 1
updatedAt: "2020-04-08T16:00:03.000Z"
__proto__: Object
length: 2
__proto__: Array(0)

, чем выборка пользователей и инструментов:

(2) [{…}, {…}]
0: {id: 1, name: "Tomáš Princ", email: "p***@seznam.cz", createdAt: "2020-04-08T15:59:54.000Z", updatedAt: "2020-04-08T15:59:54.000Z"}

1: {id: 2, name: "jhfgjhfg", email: "admin@admin.cz", createdAt: "2020-04-08T18:44:16.000Z", updatedAt: "2020-04-08T18:44:16.000Z"}
length: 2
__proto__: Array(0)
[{…}]
0: {id: 1, code: "guhf", name: "jhfh", state: "ghf", free: 1, …}
length: 1
__proto__: Array(0)

Я регистрирую эти json данные в DataProvider и возвращаю их как данные: json

switch (type) {
            case GET_LIST:
            case GET_MANY:
            case GET_MANY_REFERENCE:
                console.log(json)
                console.log(type)
                if (!headers.has('content-range')) {
                    throw new Error(
                        'The Content-Range header is missing in the HTTP Response. The simple REST data provider expects responses for lists of resources to contain this header with the total number of results to build the pagination. If you are using CORS, did you declare Content-Range in the Access-Control-Expose-Headers header?'
                    );
                }
                console.log((headers.get('content-range')))
                return {

                    data: json,
                    total: 
                    //json.length, 
                    parseInt(
                        headers
                            .get('content-range')
                            .split('/')
                            .pop(),
                        10
                    ),
                };

Так что приложение выглядит так, как будто все данные ему нужны, но по какой-то причине все еще загрузка и ожидание чего-либо.

РЕДАКТИРОВАТЬ 2: Я попытался немного обойти, создав пользовательский элемент, который загружает userId и toolId и выбирает запрос classi c для получения пользователя / инструмента по ID для каждой строки. Это работает.

const ToolCode = ({ record = {} }) => {

    const dataProvider = useDataProvider();
    const [tool, setTool] = useState();
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState();
    useEffect(() => {
        dataProvider.getOne('tools', { id: record.ToolId })
            .then(({ data }) => {
                setTool(data);
                setLoading(false);
            })
            .catch(error => {
                setError(error);
                setLoading(false);
            })
    }, []);

    if (loading) return <Loading />;
    if (error) return <Error />;
    if (!tool) return null;
    console.log("fetch tools")
    return (
        tool.code
    )
};

const UserName = ({ record = {} }) => {
    const dataProvider = useDataProvider();
    const [user, setUser] = useState();
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState();
    useEffect(() => {
        dataProvider.getOne('users', { id: record.UserId })
            .then(({ data }) => {
                setUser(data);
                setLoading(false);
            })
            .catch(error => {
                setError(error);
                setLoading(false);
            })
    }, []);

    if (loading) return <Loading />;
    if (error) return <Error />;
    if (!user) return null;

    return (
        user.name
    )
};




const B_toolFilter = (props) => (
    <Filter {...props}>
        <TextInput label="Search" source="q" alwaysOn />
        <TextInput label="Title" source="title" defaultValue="Hello, World!" />
    </Filter>
);


export const B_toolList = props => (
    <List {...props}>
        <Datagrid rowClick="edit">
            <TextField source="id" />
            <NumberField source="active" />
            <NumberField source="time" />
            <DateField source="createdAt" />
            <DateField source="updatedAt" />
            <UserName source="UserId" />
            <ToolCode source="ToolId" />            
        </Datagrid>
    </List>
);

Теперь я могу получить код инструмента и имя пользователя по идентификаторам из B_Tools, но это гораздо менее эффективно, чем метод GET_MANY, используемый ReferenceField ..

1 Ответ

0 голосов
/ 14 апреля 2020

Nwm. Все время это были только заглавные буквы Инструментов и Пользователей в

     <ReferenceField source="UserId" reference="Users">

и

     <ReferenceField source="ToolId" reference="Tools">

Я изменяю его на

     <ReferenceField source="UserId" reference="users">

и

     <ReferenceField source="ToolId" reference="tools">

Теперь это работает! Я просто до сих пор не понимаю, почему он выбрал правильные ресурсы ... Как будто он не чувствителен к капиталу при получении данных, но он чувствителен к капиталу при рендеринге. Я не знаю. В любом случае, я бы ожидал какое-то сообщение об ошибке с такой ошибкой, а не просто правильный ответ и пустой рендер.

...