【问题标题】:React-Admin is populating my <List> with same elementReact-Admin 正在用相同的元素填充我的 <List>
【发布时间】:2020-01-24 07:24:40
【问题描述】:

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.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 中工作正常:

【问题讨论】:

  • 你确定你得到了不同的用户响应吗????
  • 如果是,那么请添加您要在前端渲染的代码
  • @PrakashKarena 添加了前端代码,是的,用邮递员测试过,工作正常...
  • 这里是邮递员回复的快照:i.stack.imgur.com/IP9FW.png
  • 每条记录都需要一个id 字段,您的似乎错过了它。控制台应显示有关它的警告。

标签: reactjs spring spring-boot spring-mvc react-admin


【解决方案1】:

从 API 消费数据的永无止境的挑战

以上答案中所说的都是真的!
根据所提出的问题,您如何为&lt;Datagrid&gt; 提供一个id 字段来迭代您的数据并唯一地呈现每一行/元素?

请注意,React-Admin dataProvider 通常会返回带有 json Object {count: &lt;Number&gt;, results: &lt;Array&gt;} 的响应。结果数组通常映射到数据键上,例如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-adminreact.js 的客户更容易使用您的数据。

  2. 好的,所以您无法控制该后端 (API)!
    然后你必须使用这条线//data: json.map(record =&gt; ({"id": record.userID, ...record}))

解决方案二不要太快!
在使用 API 时存在最常见的陷阱。
当我们获取数据时,我们的客户端最初(数组/列表,在本例中为json.results)是未定义的。
所以javascript 会抱怨它cannot read property 'map' of undefined

我该如何解决undefined这样的挑战?

直接以array 启动您的数据,或指示map() 仅在您的数据未定义时运行(通过包含此类检查,typeof json !== ‘undefined’)。

【讨论】:

    【解决方案2】:

    在这里试试:

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

    每条记录必须有一个名为 id 的字段,在您的情况下代表您的 userID 字段。

    使用 users 作为资源名称,而不是 user

    如果您无法更改该服务器端,您可以在 javascript 中进行。

    以下示例代码应该可以工作。 将其添加到您的设置中的AdminPanel.js 文件中:

    使用您的后端,取消注释以下行:

    //data: json.map(record =&gt; ({"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}/>
    
    

    【讨论】:

    • 它给了我map undefined 错误,所以我将data.map 更改为json.map 它解决了这个问题,但又给了我另一个新错误:has of undefined,你可以看到它正在正确返回数据现在:数据:数组(18)
    • 很抱歉。我没有测试它。 has 错误是由于 headers 变量未在 Promise 中返回,因为 ra-data-simple-rest 尝试使用标头的 has 方法,而 headers 参数为 undefined。我已经更正了示例以包含它。
    • 我现在无法测试代码。你在哪一行得到了这个错误?
    • 好吧,你要传data属性,我再换个例子。对不起。
    • @MaifeeUlAsad,我设置了另一个应该可以工作的例子。请检查一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    • 2017-02-08
    • 2011-10-07
    • 1970-01-01
    • 2012-03-06
    • 2019-11-22
    • 1970-01-01
    相关资源
    最近更新 更多