React-Admin заполняет мой <List>тем же элементом - PullRequest
1 голос
/ 24 января 2020

codesandbox.io

Я пытаюсь создать хорошую панель администратора с react-admin. Как использовать spring в моем бэкэнде, и вот как я отправляю данные на react-admin:

@GetMapping("admin/user")
ResponseEntity<List<User>> getAll()
{
   System.out.println(new Date());;

   HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set("Content-Range", "posts 0-"+userRepository.findAll().size() + "/" + userRepository.findAll().size());
        responseHeaders.set("Origin", "http://localhost:3001");

    return ResponseEntity.ok()
             .headers(responseHeaders)
             .body(userRepository.findAll());
}

Во-первых, это не работает, а во-вторых, это даже близко не подходит к правильному решению. .

К сожалению, мой клиент отрисовывает последнюю вещь снова и снова. Как вы можете видеть ниже , элемент с id 129 отображается снова и снова!

react-admin populating list with same element

На внешнем интерфейсе, в пределах react.js:

// Within main/parent component
class App extends Component {
  render() {
    return (
      <Admin dataProvider={restProvider('http://localhost:8080/admin')}>
         <Resource name="user" list={UserList}/>
      </Admin>
    );
  }
};

// child component
const UserList = (props) => (
   <List {...props}>
      <Datagrid>
         <TextField source="userID" />
         <TextField source="username" />
         <TextField source="firstName" />
         <TextField source="middleName" />
         <TextField source="lastName" />
         <TextField source="profileImageURL" />
         <DateField source="joiningTime" />
         <EditButton basePath="/posts" />
       </Datagrid>
    </List>
);

Я думаю, мне нужен метод, который вроде бы настраивает каждый ответ контроллера с Content-Range заголовком .

Обратите внимание, что мой возвращенный данные отлично работают в postman:

react-admin populating list with same element

Ответы [ 2 ]

1 голос
/ 26 января 2020

Попробуйте здесь:

https://codesandbox.io/s/react-admin-sample-l692r

Каждая запись должна иметь поле с именем id, которое в вашем случае представляет ваш userID field.

Используйте users для имени ресурса вместо user.

Если вы не можете изменить эту сторону сервера, вы можете сделать это в javascript.

Следующий пример кода должен работать. Добавьте его в файл AdminPanel.js в настройках:

С помощью своего бэкэнда раскомментируйте следующие строки:

//data: json.map(record => ({"id": record.userID, ...record})),

//total: parseInt(headers.get('content-range').split('/').pop(), 10),

И измените следующую строку:

const apiUrl = "https://jsonplaceholder.typicode.com";

на

const apiUrl = "http://localhost:8080/admin";

import React from "react";
import { Admin, Resource, fetchUtils } from "react-admin";
import restProvider from "ra-data-simple-rest";
import { UserList, LoginCredentialList } from "./posts";
import { stringify } from "query-string";

const apiUrl = "https://jsonplaceholder.typicode.com";
const httpClient = fetchUtils.fetchJson;

const myDataProvider = {
    ...restProvider,
    getList: (resource, params) => {
        const { page, perPage } = params.pagination;
        const { field, order } = params.sort;
        const query = {
            sort: JSON.stringify([field, order]),
            range: JSON.stringify([(page - 1) * perPage, page * perPage - 1]),
            filter: JSON.stringify(params.filter)
        };
        const url = `${apiUrl}/${resource}?${stringify(query)}`;

        return httpClient(url).then(({ headers, json }) => ({
            data: json,
            //data: json.map(record => ({"id": record.userID, ...record})),
            total: 10, //temporary hardcoded to avoid headers error.
            //total: parseInt(headers.get('content-range').split('/').pop(), 10),
        }));
    }
};

class AdminPanel extends React.Component {
    render() {
        return (
          <div>
              <Admin dataProvider={myDataProvider}>
                  <Resource name="users" list={UserList} />
                  <Resource name="loginCredential" list={LoginCredentialList} />
              </Admin>
          </div>
        );
    }
}

export default AdminPanel;

//                  <Resource name="posts" list={UserList} edit={PostEdit} create={PostCreate}/>

0 голосов
/ 05 марта 2020

Бесконечная проблема потребления данных из API

Все, что сказано в ответе выше, верно! Основываясь на заданном вопросе, как вы предоставляете поле id для <Datagrid> для перебора ваших данных и уникальной визуализации каждой строки / элемента?

Обратите внимание, что React-Admin dataProvider часто возвращает ответ с json Object {count: <Number>, results: <Array>}. И массив результатов часто отображается на ключ данных, например data: json.results

Here's what helped me while I used react-admin with a python/django backend. Я полагаю, что в большинстве случаев, независимо от серверной части, важно понимать, как react-admin потребляет данные (в данном случае list). Возможны два решения:

  1. Если у вас есть контроль над бэкэндом (API), как здесь. Затем, пожалуйста, обновите / измените рефакторинг вашего уникального идентификатора (в данном случае userID), чтобы отобразить / вернуть его как простое поле id. Это облегчит работу любого клиента, использующего ваши данные, используя, как правило, react-admin или react.js.

  2. Хорошо, так что вы не можете контролировать этот бэкэнд (API)! Тогда вам придется использовать эту строку //data: json.map(record => ({"id": record.userID, ...record})).

Не так быстро с решением два! В работе с API лежит самая распространенная ошибка. Пока мы выбираем данные, наш клиент изначально (массив / список, в нашем случае json.results) не определен. Так что javascript будет жаловаться, что это cannot read property 'map' of undefined.

Как мне решить такую ​​проблему undefined?

Либо напрямую инициируйте ваши данные как array, либо дайте команду map() запускаться, только если ваши данные не определены (включая такую ​​проверку, typeof json !== ‘undefined’).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...