Создание приложений на основе данных с 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)
}
Discover how at OpenReplay.com.
Создание представлений списков и редактирования
После настройки 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.