如何使用 React 构建管理面板

2025-05-25

如何使用 React 构建管理面板

作者:拉斐尔·乌古✏️

介绍

许多 Web 应用已经从仅显示内容的静态网站发展成为用户可访问和交互的动态网页。这些内容通常由发送和接收数据的 API 提供支持。

通常需要一个管理页面来排序和处理这些数据。通常的做法是构建一个接口,并通过向 API 发送请求来连接每个端点。在react-admin引入之前,这曾经是一个繁琐的过程。

react-admin是一个通过使用您的 API(Rest、GraphQL 或自定义 API)来构建管理界面的框架。您也无需担心样式格式,因为它以Material UI(一个用于设计应用程序界面的 React 库)为主题。在本篇博文中,我们将学习如何react-admin为应用程序构建管理界面。

LogRocket 免费试用横幅

入门

让我们首先创建一个新的 React 项目并react-admin在其目录中安装,如下所示:

npx create-react-app react-admin-app
cd react-admin-app
# install react-admin
npm install react-admin
Enter fullscreen mode Exit fullscreen mode

您的应用程序应该在端口 3000 上使用空的 React 应用程序运行。

使用猜测器修改和过滤数据

管理页面必须具备 CRUD 功能。我们将使用 API 来演示如何react-admin实现这一点。JSONPlaceholder是一个虚拟的 REST API,仅用于演示目的。以下是我们将获取的数据示例:

{
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "Sincere@april.biz",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
  }
Enter fullscreen mode Exit fullscreen mode

我们首先需要在我们的react-admin应用程序中安装 JSONPlaceholder:

npm install ra-data-json-server prop-types
Enter fullscreen mode Exit fullscreen mode

让我们尝试从 API 获取数据。为此,react-admin它使用<Admin>其根组件 来提供 API 和应用程序之间的数据交换。将 中的默认语法替换为src/App.js以下内容:

import React, { Component } from "react";
import { Admin } from "react-admin";
import jsonServerProvider from "ra-data-json-server";

const dataProvider =
  jsonServerProvider("https://jsonplaceholder.typicode.com");

class App extends Component {
  render() {
    return (
      <Admin dataProvider={dataProvider} />
    );
  }
}
export default App;
Enter fullscreen mode Exit fullscreen mode

npm start此时运行应该会在浏览器上呈现一个带有确认消息的应用程序:

反应管理面板界面

虽然仍在开发中,但react-admin通过“猜测器”创建管理界面。猜测器从 API 接收数据,确定数据的类型,然后决定以何种格式显示数据。让我们尝试通过应用猜测器来显示用户列表:

import React, { Component } from "react";
import { Admin, Resource, ListGuesser } from "react-admin";
import jsonServerProvider from "ra-data-json-server";

const dataProvider =
  jsonServerProvider("https://jsonplaceholder.typicode.com");

class App extends Component {
  render() {
    return (
      <Admin dataProvider={dataProvider}>
        <Resource name="users" list={ListGuesser} />
      </Admin>
    );
  }
}
export default App;
Enter fullscreen mode Exit fullscreen mode

在上面的代码块中,<resource>元素负责将name属性映射到 API 中的端点。这里<resource>users值附加到我们的 API,并从 API 中获取用户数据。list属性使用组件<ListGuesser>将此数据显示为用户列表。

控制台中的数据显示

<ListGuesser>它不适用于生产环境,因此必须用自定义组件替换。猜测器的一个很棒的功能是将从 API 检索到的数据的源代码显示在浏览器控制台中。我们来看看它<ListGuesser>显示了什么:

控制台中显示的数据

这向我们展示了如何创建用户列表。让我们在应用程序中复制这些数据。在src项目文件夹中,创建一个文件并将其命名为users.js

/src/users.js
import React from 'react';
import { List, Datagrid, TextField, EmailField, UrlField } from 'react-admin';
export const UserList = props => (
    <List {...props}>
        <Datagrid rowClick="edit">
            <TextField source="id" />
            <TextField source="name" />
            <TextField source="username" />
            <EmailField source="email" />
            <TextField source="address.street" label="Address" />
            <TextField source="phone" />
            <UrlField source="website" />
            <TextField source="company.name" label="Company" />
        </Datagrid>
    </List>
);
Enter fullscreen mode Exit fullscreen mode

上面的代码块做了一些修改。首先,我们使用<UrlField>元素使网站列上的链接可点击。然后,我们label为地址和公司列添加一个属性,使它们的标题更具可读性。让我们导航到App.js并将其替换ListGuesserUserList

/src/App.js

import React, { Component } from "react";
import { Admin, Resource } from "react-admin";
import { UserList } from './users';
import jsonServerProvider from "ra-data-json-server";

const dataProvider =
  jsonServerProvider("https://jsonplaceholder.typicode.com");

class App extends Component {
  render() {
    return (
      <Admin dataProvider={dataProvider}>
        <Resource name="users" list={UserList} />
      </Admin>
    );
  }
}
export default App;
Enter fullscreen mode Exit fullscreen mode

管理页面也应该能够编辑和创建数据。react-admin也可以通过使用猜测器来实现这一点。EditGuesser用于编辑管理页面的数据。在 中App.jsEditGuesser从导入react-admin

src/App.js

import React from 'react';
import { Admin, Resource, EditGuesser } from "react-admin";
import { UserList } from './users';

class App extends Component {
  render() {
    return (
      <Admin dataProvider={dataProvider}>
        <Resource
          name="users"
          list={UserList}
          edit={EditGuesser}
        />
      </Admin>
    );
  }
}     
Enter fullscreen mode Exit fullscreen mode

现在我们可以在管理界面上编辑用户详细信息:

需要注意的是,我们使用的 JSONPlaceholder API 不具备编辑和创建功能。这里采用了一种称为乐观渲染的概念——它react-admin用于在后台发送更新查询的同时显示所做的更改。如果查询失败,数据将恢复到其原始形式。

与列出用户类似,查看控制台可以让我们了解应该输入哪些标记。使用 后,我们得到的结果如下EditGuesser

让我们在应用程序中复制控制台的标记。将下面的代码示例附加到users.js

//src/users.js
import React from 'react';
import { Edit, UrlField, DisabledInput, SimpleForm, TextInput } from 'react-admin';

export const UserEdit = props => (
    <Edit {...props}>
      <SimpleForm>
        <DisabledInput source="id" />
        <TextInput source="name" />
        <TextInput source="username" />
        <TextInput source="email" />
        <TextInput source="address.street" label="Address" />
        <TextInput source="phone" />
        <UrlField source="website" />
        <TextInput source="company.name" label="Company" />
      </SimpleForm>
    </Edit>
  );
Enter fullscreen mode Exit fullscreen mode

DisabledInput元素可防止敏感属性被编辑。在 中App.js,替换EditGuesserUserEdit

//src/App.js
import React, { Component } from "react";
import { Admin, Resource } from "react-admin";
import  { UserList, UserEdit }  from './users';
import jsonServerProvider from "ra-data-json-server";
const dataProvider =
  jsonServerProvider("https://jsonplaceholder.typicode.com");
class App extends Component {
  render() {
    return (
      <Admin dataProvider={dataProvider}>
        <Resource name="users" list={UserList} edit={UserEdit} />
      </Admin>
    );
  }
}
export default App;
Enter fullscreen mode Exit fullscreen mode

创建新用户的过程与编辑保存的几个元素几乎相同。在 中users.js,复制以下代码示例:

//src/users.js
import React from 'react';
import { Create, UrlField, DisabledInput, SimpleForm, TextInput } from 'react-admin';

export const UserCreate = props => (
    <Create {...props}>
      <SimpleForm>
        <TextInput source="name" />
        <TextInput source="username" />
        <TextInput source="email" />
        <TextInput source="address.street" label="Address" />
        <TextInput source="phone" />
        <UrlField source="website" />
        <TextInput source="company.name" label="Company" />
      </SimpleForm>
    </Create>
  );
Enter fullscreen mode Exit fullscreen mode

App.js添加UserCreate组件:

//src/App.js
import React, { Component } from "react";
import { Admin, Resource } from "react-admin";
import  { UserList, UserEdit, UserCreate }  from './users';
import jsonServerProvider from "ra-data-json-server";
const dataProvider =
  jsonServerProvider("https://jsonplaceholder.typicode.com");
class App extends Component {
  render() {
    return (
      <Admin dataProvider={dataProvider}>
        <Resource name="users" list={UserList} edit={UserEdit} create={UserCreate} />
      </Admin>
    );
  }
}
export default App;
Enter fullscreen mode Exit fullscreen mode

在我们的界面上,让我们尝试创建一个新用户:


与我们尝试编辑用户详细信息时发生的情况类似,乐观渲染也会发生。这解释了为什么在上面代码片段的最后几秒,我们新创建的用户会显示一段时间,然后NOT FOUND才能看到消息。

验证

每个管理页面都需要身份验证流程。身份验证方式可能很简单,也可能比较复杂(例如 JWT、OAuth)。虽然默认情况下,react-admin应用程序无需身份验证即可运行,但将身份验证集成到管理页面仍然是最佳实践。

react-admin让您可以灵活地实现身份验证。JSONPlaceholder 没有身份验证模型,因此我们将创建一个虚拟身份验证流程,它将接受任何值作为 和 ,username并将password这些值存储在 中localStorage。在您的src文件夹中,创建一个名为 的文件authProvider

// src/authProvider.js
import { AUTH_LOGIN, AUTH_LOGOUT, AUTH_ERROR, AUTH_CHECK } from 'react-admin';

   export default (type, params) => {
    // when a user tries to log in 
    if (type === AUTH_LOGIN) {
     const { username } = params;
     localStorage.setItem('username', username)
     return Promise.resolve();
    }
    // when a user tries to logout
    if (type === AUTH_LOGOUT) {
     localStorage.removeItem('username', username)
     return Promise.resolve();
    }
    // when the API throws an error
    if (type === AUTH_ERROR) {
     const { status } = params;
     if (status === 401 || status === 403) {
      localStorage.removeItem('username');
      return Promise.reject()
     }
     return Promise.resolve()
    }
    // when a user navigates to a new location
    if (type === AUTH_CHECK) {
     return localStorage.getItem('username') ?
      Promise.resolve() :
      Promise.reject();
    }
    return Promise.reject('Unknown Method');
   };
Enter fullscreen mode Exit fullscreen mode

然后继续App.js并传递组件authProvider中的属性<Admin>

//src/App.js
import React, { Component } from "react";
import { Admin, Resource } from "react-admin";
import authProvider from "./authProvider";
import  { UserList, UserEdit, UserCreate }  from './users';
import jsonServerProvider from "ra-data-json-server";
const dataProvider =
  jsonServerProvider("https://jsonplaceholder.typicode.com");
class App extends Component {
  render() {
    return (
      <Admin dataProvider={dataProvider} authProvider={authProvider}>
        <Resource name="users" list={UserList} edit={UserEdit} create={UserCreate} />
      </Admin>
    );
  }
}
export default App;
Enter fullscreen mode Exit fullscreen mode

现在,当我们重新启动应用程序时,我们首先进入登录页面:

概括

创建管理应用程序不再像以前那么复杂。有了它react-admin,我们可以很容易地搭建管理界面。身份验证过程同样重要,本文也不例外。如果您需要查看源代码,可以在 CodeSandBox上找到。


编者注:觉得这篇文章有什么问题?您可以在这里找到正确版本

插件:LogRocket,一个用于 Web 应用的 DVR

 
LogRocket 仪表板免费试用横幅
 
LogRocket是一款前端日志工具,可让您重放问题,就像它们发生在您自己的浏览器中一样。您无需猜测错误发生的原因,也无需要求用户提供屏幕截图和日志转储,LogRocket 允许您重放会话以快速了解问题所在。它可与任何应用程序完美兼容,无论使用哪种框架,并且提供插件来记录来自 Redux、Vuex 和 @ngrx/store 的更多上下文。
 
除了记录 Redux 操作和状态之外,LogRocket 还记录控制台日志、JavaScript 错误、堆栈跟踪、带有标头 + 正文的网络请求/响应、浏览器元数据以及自定义日志。它还会对 DOM 进行插桩,以记录页面上的 HTML 和 CSS,即使是最复杂的单页应用程序,也能重现像素完美的视频。
 
免费试用


如何使用 React 构建管理面板一文首先出现在LogRocket 博客上。

文章来源:https://dev.to/bnevilleoneill/how-to-build-an-admin-panel-with-react-4gf1
PREV
如何像专业人士一样使用 CSS 变量
NEXT
在 Docker 上使用 Node.js 和 ElasticSearch 进行全文搜索