Back

Создание приложений на основе данных с React Admin

Создание приложений на основе данных с React Admin

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

Ключевые выводы

  • React Admin — это React-фреймворк для создания административных панелей на основе данных, а не UI-шаблон. Он разделяет слой данных и слой UI через абстракцию dataProvider.
  • dataProvider построен на основе девяти базовых методов, которые адаптируют React Admin к любому бэкенду — REST, GraphQL, Supabase или другим — делая фреймворк действительно независимым от бэкенда.
  • Представления списков и редактирования являются декларативными: вы компонуете компоненты полей и компоненты ввода, а React Admin автоматически обрабатывает получение данных, пагинацию, сортировку и разрешение связей.
  • Аутентификация, управление доступом на основе ролей и обновления в реальном времени обрабатываются через отдельные провайдеры и опциональные расширения, сохраняя ядро фреймворка сфокусированным и модульным.

Что на самом деле представляет собой React Admin

React Admin — это не UI-шаблон. Это React-фреймворк, специально созданный для административных панелей на основе данных и внутренних инструментов. Он поставляется с компонентами для отображения списков, создания, редактирования и удаления записей, но реальная ценность заключается в том, как он разделяет слой данных и слой UI.

В своей основе React Admin v5 построен на React Query, react-hook-form и react-router. По умолчанию используется MUI, но фреймворк не ограничивается им — React Admin поддерживает headless-режим, что означает возможность использовать собственную библиотеку компонентов при необходимости.

Три строительных блока: Admin, Resource и dataProvider

Каждое приложение React Admin начинается с трёх концепций:

  • <Admin> — корневой компонент, который связывает всё воедино
  • <Resource> — сопоставляет имя с набором CRUD-представлений и API-эндпоинтом
  • dataProvider — адаптер между React Admin и вашим бэкендом
import { Admin, Resource } from "react-admin"
import { dataProvider } from "./dataProvider"
import { MovieList } from "./MovieList"
import { MovieEdit } from "./MovieEdit"

const App = () => (
  <Admin dataProvider={dataProvider}>
    <Resource name="movies" list={MovieList} edit={MovieEdit} />
  </Admin>
)

Когда пользователь переходит к списку фильмов, React Admin вызывает dataProvider.getList("movies", params). Когда он редактирует запись, вызывается dataProvider.update("movies", params). UI никогда не обращается к вашему API напрямую.

Как работает dataProvider в React Admin

dataProvider построен на основе девяти базовых методов: getList, getOne, getMany, getManyReference, create, update, updateMany, delete и deleteMany. Каждый метод получает объект запроса и возвращает Promise, а провайдеры могут быть расширены дополнительными методами при необходимости.

const dataProvider = {
  getList: async (resource, params) => {
    const { page, perPage } = params.pagination
    const { field, order } = params.sort
    const url = `${apiUrl}/${resource}?page=${page}&perPage=${perPage}&sort=${field}&order=${order}`
    const { json, headers } = await httpClient(url, { signal: params.signal })
    return {
      data: json,
      total: parseInt(headers.get("content-range").split("/").pop(), 10),
    }
  },
  // ...другие методы
}

React Admin не важно, является ли ваш бэкенд REST, GraphQL, Supabase или даже IndexedDB. Пока каждая запись имеет согласованное поле id, а ваш dataProvider возвращает ожидаемую структуру, всё работает. Существуют готовые адаптеры для распространённых бэкендов — ra-data-simple-rest, ra-data-graphql и другие — поэтому часто не требуется писать адаптер с нуля.

Обработка аутентификации

Аутентификация не встроена в dataProvider. React Admin использует отдельный authProvider для входа, выхода и проверки прав доступа. Распространённый паттерн — сохранять токен после входа и читать его внутри вашего dataProvider при выполнении запросов, но React Admin также поддерживает интеграцию с внешними провайдерами идентификации.

const httpClient = (url, options = {}) => {
  options.user = {
    authenticated: true,
    token: localStorage.getItem("token"),
  }
  return fetchUtils.fetchJson(url, options)
}

Создание представлений списков и редактирования

После настройки dataProvider создание представлений становится в основном декларативным. Для представлений списков компонент React Admin <Datagrid> отображает столбцы на основе компонентов полей, которые вы компонуете. Обратите внимание, что <Datagrid> по-прежнему широко используется, но в новых версиях также представлен <DataTable> как более современная альтернатива.

import { List, Datagrid, TextField, DateField, ReferenceField } from "react-admin"

export const MovieList = () => (
  <List>
    <Datagrid rowClick="edit">
      <TextField source="title" />
      <DateField source="release" />
      <ReferenceField source="director_id" reference="directors">
        <TextField source="lastname" />
      </ReferenceField>
    </Datagrid>
  </List>
)

<ReferenceField> автоматически вызывает dataProvider.getMany("directors", ...) для разрешения связанных записей — ручная загрузка не требуется.

Формы редактирования следуют тому же паттерну с использованием <Edit> и <SimpleForm>:

import { Edit, SimpleForm, TextInput, DateInput } from "react-admin"

export const MovieEdit = () => (
  <Edit>
    <SimpleForm>
      <TextInput source="title" />
      <DateInput source="release" />
    </SimpleForm>
  </Edit>
)

Когда требуется пользовательская логика

Для поведения, специфичного для ресурса — например, удаления связанных записей перед удалением родительской — React Admin предоставляет withLifecycleCallbacks:

import { withLifecycleCallbacks } from "react-admin"

export const dataProvider = withLifecycleCallbacks(baseDataProvider, [
  {
    resource: "movies",
    beforeDelete: async (params, dp) => {
      const { data: reviews } = await dp.getList("reviews", {
        filter: { movie_id: params.id },
        pagination: { page: 1, perPage: 1000 },
        sort: { field: "id", order: "DESC" },
      })
      await dp.deleteMany("reviews", { ids: reviews.map((r) => r.id) })
      return params
    },
  },
])

Это позволяет держать вашу бизнес-логику близко к слою данных, не распыляя её по компонентам.

Что React Admin не делает из коробки

Несколько моментов, которые стоит знать, прежде чем вы примете решение:

  • RBAC (детализированное управление доступом на основе ролей) требует корпоративного модуля; базовые проверки прав доступа обрабатываются через authProvider
  • Обновления в реальном времени требуют совместимого realtime data provider и дополнительной настройки
  • Загрузка файлов требует пользовательской логики dataProvider для обработки multipart/form-data

React Admin также совместим с фреймворками, такими как Next.js (включая Pages Router и App Router), и поддерживает альтернативные решения для маршрутизации помимо настроек по умолчанию.

Заключение

Сила React Admin заключается в его абстракции dataProvider. После того как вы реализуете эти базовые методы для вашего API, вы получаете полнофункциональную CRUD-панель администрирования с сортировкой, фильтрацией, пагинацией и обработкой связей — без необходимости создавать всё это самостоятельно. Начните с готового адаптера, если он подходит для вашего бэкенда, напишите пользовательский, если нет, и добавляйте аутентификацию и lifecycle callbacks по мере роста вашего приложения.

Часто задаваемые вопросы

Да. React Admin по своей природе независим от бэкенда. Вы можете использовать официальный адаптер ra-data-graphql или написать пользовательский dataProvider, который сопоставляет необходимые методы с вашими GraphQL-запросами и мутациями. Пока каждая запись включает согласованное поле id, а ваш провайдер возвращает ожидаемую структуру ответа, React Admin работает одинаково независимо от бэкенда.

React Admin предоставляет компоненты ссылок, такие как ReferenceField и ReferenceInput, которые автоматически загружают связанные записи через ваш dataProvider. Например, ReferenceField вызывает dataProvider.getMany для разрешения внешних ключей в отображаемые значения. Вы объявляете связь в дереве компонентов, а React Admin обрабатывает загрузку данных и кэширование за кулисами.

Open-source версия поддерживает базовую аутентификацию и простые проверки прав доступа через authProvider. Для детализированного управления доступом на основе ролей, такого как скрытие полей или ограничение действий по ролям, требуется корпоративный RBAC-модуль. Оцените ваши требования к правам доступа заранее, чтобы решить, соответствует ли бесплатная версия вашим потребностям.

Да. React Admin по умолчанию использует MUI, но поддерживает headless-режим, что означает возможность замены всего UI-слоя на вашу собственную библиотеку компонентов. Вы также можете настроить тему MUI, переопределить отдельные компоненты или создать полностью пользовательские представления, продолжая использовать хуки React Admin для загрузки данных, обработки форм и маршрутизации.

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay