Разработка личного кабинета клиента на React

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

Обычной практикой при создании интерфейса является подключение каждого endpoint к конкретному API-запросу. С использованием фреймворка react-admin этот процесс стал намного проще и быстрее. React-admin – это фреймворк, который был создан специально для разработки интерфейсов администратора путем взаимодействия с API – через Rest, GraphQL или кастомные схемы. Вам не придется беспокоиться о форматировании стилей, так как фреймворк основан на с Material UI – библиотеке React, используемой при разработке интерфейсов приложений.

Вероятно, в разработке мособлеирц личный кабинет клиента применяли различные технологии, которые делают его удобным для пользователей.

Установка React и React-Admin

Для начала создадим новый проект на React и установим react-admin. Для это выполняем следующие команды:

npx create-react-app react-admin-demo-app
cd react-admin-demo-app/
npm i react-admin ra-data-json-server prop-types
npm start

Теперь ваше пустое приложение на React должно запуститься и работать на порту 3000.

API как источник данных

Для работы нашей панели администратора важно иметь функции CRUD. Для этого будем использовать API, чтобы показать, как реагирует приложение на наши действия. Воспользуемся JSONPlaceholder – фиктивным REST API, который существует для демонстрационных целей.

Пример вывода при обращении к данному API:

curl https://jsonplaceholder.typicode.com/users/4
{
  "id": 4,
  "name": "Patricia Lebsack",
  "username": "Karianne",
  "email": "[email protected]",
  "address": {
    "street": "Hoeger Mall",
    "suite": "Apt. 692",
    "city": "South Elvis",
    "zipcode": "53919-4257",
    "geo": {
      "lat": "29.4572",
      "lng": "-164.2990"
    }
  },
  "phone": "493-170-9623 x156",
  "website": "kale.biz",
  "company": {
    "name": "Robel-Corkery",
    "catchPhrase": "Multi-tiered zero tolerance productivity",
    "bs": "transition cutting-edge web services"
  }
}

Давайте попробуем извлечь данные из API. Для этой цели react-admin использует <Admin> – корневой компонент, чтобы обеспечить обмен данными между API и приложениями. Изменим код по умолчанию в src/App.js следующим образом:

//src/App.js
import React from 'react';
import { Admin } from 'react-admin';
import jsonServerProvider from 'ra-data-json-server';

const dataProvider = jsonServerProvider('https://jsonplaceholder.typicode.com');
const App = () => <Admin dataProvider={dataProvider} />;

export default App;

После такого изменения в окне браузера мы должны увидеть следующий экран:

React Admin вывод по умолчанию

В процессе разработки, react-admin создает интерфейсы используя компонент “guessers” (“провидцы”). При получении данных ListGuesser анализирует лучший способ отображения данных. Добавим в код <ListGuesser> и посмотрим на полученный результат:

//src/App.js показаны только измененные сроки
import { Admin, Resource, ListGuesser } from 'react-admin';
...
const App = () => (
  <Admin dataProvider={dataProvider}>
    <Resource name='users' list={ListGuesser} />
  </Admin>
);
...

Параметр list = {ListGuesser} означает, что react admin должен использовать компонент <ListGuesser> для отображения списка сообщений. 

Результат работы вышестоящего кода с ListGuesser

Строка <Resource name="users" /> сообщает react-admin получить “users” из API URL. <Resource> также определяет компоненты React, которые будут использоваться для каждой операции CRUD. Если сейчас открыть Web Developer Tools в браузере, то можно увидеть, что /users был автоматически добавлен к dataProvider URL, после чего был получен результат.

Стоит помнить, что компонент <ListGuesser> не предназначен для использования в production, поэтому его необходимо заменить пользовательским компонентом. Удивительной особенностью гессеров является отображение исходного кода данных, полученных из API, в консоли браузера.

Вывод Guessed List в косоль браузера

Это позволяет нам понять, какой вид должен иметь наш список пользователей. Давайте реализуем пользовательский компонент в нашем приложении, используя за основу предложенный гессером код. В папке 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>
);

В приведенном выше блоке кода произведено несколько изменений. <UrlField> используем для того, чтобы сделать ссылки в столбце нашего сайта кликабельными. Затем мы добавляем свойство label в столбцы адреса и компании, чтобы сделать их заголовки более презентабельными. Давайте перейдем к App.js и заменим ListGuesser на UserList.

//src/App.js показаны только измененные сроки
...
import { Admin, Resource } from 'react-admin';
import { UserList } from './users';
...
const App = () => (
  <Admin dataProvider={dataProvider}>
    <Resource name='users' list={UserList} />
  </Admin>
);
...

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

Как это все работает?

Основным компонентом списка пользователей является компонент, отвечающий за получение информации из API, отображение заголовка страницы и обработку нумерации страниц. Этот список затем делегирует отображение фактического списка пользователей его дочернему элементу. В данном случае это компонент, который отображает таблицу с одной строкой для каждой записи. <Datagrid> использует свои дочерние компоненты (<TextField>, <EmailField> и прочие), чтобы определить столбцы для визуализации. Каждый компонент <Field> отображает отдельное поле в ответе API, заданное атрибутом source.

ListGuesser создал один столбец для каждого поля в ответе. Часто это слишком много для наглядного представления, поэтому можно удалить менее важные поля или те, которые вовсе не нужны. Реализованный только что процесс, отражает начальный этап разработки с использованием react-admin. Первым делом “гадатель” выполнит работу и выдаст список, далее мы выберем необходимые для отображения поля и представим их в пользовательском компоненте для дальнейшей настройки.

Создание и редактирование данных

Любая административная панель должна давать возможность пользователю создавать и редактировать данные. React Admin также легко позволяет организовать данный процесс при помощи компонента EditGuesser. Для этого импортируем его в нашем файле App.js и добавим в компонент <Resourse>.

//src/App.js показаны только измененные строки
import { Admin, Resource, EditGuesser } from "react-admin";
...
<Resource name='users' list={UserList} edit={EditGuesser} />
...

Теперь мы можем редактировать данные пользователя в нашем интерфейсе администратора.

Важно отметить, что JSONPlaceholder, используемый нами API, не имеет функций редактирования и создания. Здесь срабатывает концепция, называемая оптимистическим рендерингом – которую react admin использует для отображения изменений, внесенных при одновременной отправке запроса на обновление в фоновом режиме. В случае сбоя запроса данные возвращаются к первоначальному виду.

Аналогично гессеру со списком пользователей, в консоли браузера можно найти код для рендеринга отображаемой в редакторе информации.

Вывод EditGuesser в консоль браузера

Перенесем предложенную структуру в наш users.js внеся несколько корректировок по полям.

export const UserEdit = props => (
  <Edit {...props}>
    <SimpleForm>
      <TextInput disabled 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>
);

Добавление disabled к полю с id предотвратит возможность его редктирования, т.к. это поле чувствительных данных и по нему может идти привязка к пользователю. Во избежание нарушения структуры БД такие поля необходимо отключить для редактирования.

В App.js заменяем EditGuesser на только что созданный компонент UserEdit:

...
import  { UserList, UserEdit }  from './users';
...
<Resource name='users' list={UserList} edit={UserEdit} />
...

Процесс создания нового пользователя похож на редактирование единичой записи. Для реализации создания пользователя добавим в users.js следующий кода:

...
import { Create, List, Datagrid, TextField, EmailField, Edit, UrlField, 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>
);

B App.js добавляем компонент UserCreate:

...
<Resource name='users' list={UserList} edit={UserEdit} create={UserCreate} />
...

Теперь мы можем создать нового пользователя.

Аналогично процессу редактирования, создание пользователя происходит с применением оптимистичного рендеринга. Запрос к серверу выполняется после отображения в браузере, после чего мы получим ошибку о том, что запись не найдена, т.к. наше демонстрационное API не поддерживает POST / PUT операции.

Примечание. Когда вы добавляете возможность редактировать элемент, вы также добавляете возможность его удаления. Кнопка «Удалить» в представлении редактирования полностью работает «из коробки», и она поддерживает отмену операции (UNDO).

На этом этапе предлагаю сделать паузу, а в следующем посте продолжим знакомство с фреймворком react admin.

1 Response

  1. Константин:

    Спасибо большое. Очень нужный материал, с превосходной подачей.

Добавить комментарий

Ваш адрес email не будет опубликован.

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.