Использование компонента Material UI DataGrid в приложении refine


Введение

В этой статье мы покажем, как использовать компонент Material UI <DataGrid/> и хук refine useDataGrid для отображения данных с имитационного API-сервера в табличной форме с помощью приложения refine.

refine — это основанный на React фреймворк для быстрой разработки приложений, управляемых данными, с помощью набора вспомогательных хуков, компонентов и провайдеров данных. refine — это безголовый фреймворк, который не включает компоненты пользовательского интерфейса по умолчанию, но имеет поддержку и конфигурации для внедрения любых библиотек пользовательского интерфейса или фреймворка на выбор, таких как Material UI или Tailwind CSS.

Material UI — это библиотека компонентов React UI с богатым набором компонентов и инструментов для создания элегантных пользовательских интерфейсов. Мы будем использовать компонент <DataGrid/> для отображения списка сотрудников с макетного сервера. Мы также рассмотрим некоторые свойства и пользовательские конфигурации, которые можно использовать с компонентом.

Шаги, которые мы рассмотрим:

  • Настройка приложения refine
  • Создание имитационного API с помощью Mockaroo и My JSON Server
  • Компонент Material UI DataGrid
  • Добавление стилизованных компонентов
  • хук refine’s useDataGrid
  • Рендеринг данных с помощью компонента DataGrid
  • Пагинация, фильтрация и сортировка с помощью хука useDataGrid.

Предварительные условия

refine — это приложение react, по умолчанию поставляемое с TypeScript. Наше учебное приложение будет написано на typescript-react, поэтому необходимо иметь хороший опыт кодирования на React и TypeScript. Также убедитесь, что у вас установлены следующие версии node и npm, чтобы избежать ошибок при работе с суперплатформой:

  • Node v16.14 или более поздней версии
  • Npm v8.3 или более поздней версии

Вы можете запустить node -v и npm -v в терминале, чтобы подтвердить установленные версии, прежде чем продолжить.

Настройка приложения refine

Существует два возможных способа создания приложения refine: использование суперплайта или добавление модуля refine в пустое приложение React. В этом руководстве мы будем использовать первый способ, так как он является рекомендуемым для начала работы.

Выполните следующую команду в терминале, чтобы создать приложение refine с помощью superplate:

npx superplate-cli -p refine-react datagrid
Войти в полноэкранный режим Выйти из полноэкранного режима

В приведенной выше команде флаг -p указывает тип проекта, который в нашем случае является проектом refine-react. datagrid — это имя, которое я выбрал в качестве названия приложения для краткости. Вы всегда можете выбрать любое название, которое вас устраивает.

Программа установки задаст вам несколько вопросов. Выберите следующие варианты, чтобы продолжить:

После того как superplate закончит создание нашего приложения, запустите npm run dev, чтобы запустить сервер разработки, а затем перейдите на localhost:8000 в браузере, чтобы просмотреть приложение. Если все прошло гладко, в браузере должно отобразиться следующее:

Создание поддельного API с помощью Mockaroo и My JSON Server

Поддельные данные о сотрудниках, которые мы собираемся отобразить в компоненте <DataGrid/>, будут созданы с помощью Mockaroo и My JSON Server. Mockaroo — это генератор случайных поддельных данных для создания до 1 000 реалистичных тестовых данных в форматах JSON, CSV и других.

My JSON Server — это поддельный онлайн REST-сервер для прототипирования API приложений без бэкенда. REST-сервер для данных JSON, которые мы будем использовать в этом учебнике, размещен здесь, а поддельные данные JSON, созданные с помощью Mockaroo, находятся на GitHub.

Компонент Material UI DataGrid

Компонент Material UI DataGrid — это расширяемый и многофункциональный компонент, используемый для отображения табличных данных в приложениях React. Среди его мощных возможностей — автоматическая пагинация, фильтрация и сортировка табличных данных и многие другие.

Компонент доступен в двух версиях: MIT <DataGrid/> и коммерческой <DataGridPro/> (Pro и Premium). Версия MIT является бесплатной для использования, в то время как коммерческая версия является платной и расширяет возможности версии MIT, такие как возможность фильтрации и сортировки нескольких столбцов одновременно.

Компонент <DataGrid/> требует двух обязательных свойств, а именно: rows и columns. Свойство columns принимает массив полей, которые используются в качестве заголовка таблицы, а свойство rows принимает массив объектов (данных) для отображения в строках таблицы.

В следующем примере показано базовое использование компонента DataGrid:

<DataGrid
  columns={[{ field: 'name' }]}
  rows={[
    { id: 1, name: 'React' },
    { id: 2, name: 'MUI' },
  ]}
/>
Вход в полноэкранный режим Выход из полноэкранного режима

Хотя refine — это безголовый фреймворк, который можно использовать с любым фреймворком пользовательского интерфейса на выбор, он имеет встроенную поддержку нескольких фреймворков пользовательского интерфейса, таких как Material UI. Модуль refine-mui, например, поставляется с некоторыми распространенными компонентами Material UI, такими как DataGrid, GridColumn и так далее.

В следующих разделах мы рассмотрим, как использовать эти компоненты с помощью хука refine useDataGrid в нашем приложении refine.

Добавление стилизованных компонентов

Мы будем использовать стилизованные компоненты для стилизации нашего приложения, поскольку refine не контролирует то, как мы выбираем стиль наших приложений. Поэтому давайте установим его и определим его типы следующим образом:

npm install styled-components && npm install --save-dev @types/styled-components
Вход в полноэкранный режим Выйти из полноэкранного режима

Далее создайте две папки: components и pages в папке src. В этих папках мы будем писать основную часть нашего кода.

Затем создайте файл Layout.tsx в папке components и добавьте в него следующий код:

// src/components/Layout.tsx

import React from 'react';
import { LayoutProps } from "@pankod/refine-core";
import styled from 'styled-components';

const Wrapper = styled.div`
  width: 80%;
  margin: 50px auto;
  height: 100%;
`;

const Layout: React.FC<LayoutProps> = ({children}) => {
    return (
        <>
            <Wrapper>
                {children}
            </Wrapper>
        </>
    );
}

export default Layout;
Вход в полноэкранный режим Выйти из полноэкранного режима

Выше мы создаем div, чтобы обернуть содержимое нашего приложения через реквизит children, а затем выравниваем его по центру страницы.

Хук useDataGrid в refine

В дополнение к интеграции компонентов MUI, refine предоставляет чистый интерфейс через хук useDataGrid для реализации некоторых свойств, которые могут быть использованы с компонентом MUI <DataGrid/>. Хук упрощает работу с такими функциями, как пагинация, сортировка и фильтрация, которые поставляются «из коробки».

Например, если у вас есть компонент страницы, где вы хотите отобразить табличные данные, вы можете сделать что-то вроде следующего:

// src/pages/example.tsx

import React from'react'
import { useDataGrid, DataGrid, GridColumns } from "@pankod/refine-mui"

const Table: React.FC = () => {
    const { dataGridProps } = useDataGrid();
    const columns: GridColumns = [
        {
            field: "id",
            headerName: "ID",
        },
        { 
            field: "name",
            headerName: "Name" 
        },
        { 
            field: "Age",
            headerName: "Age" 
        },
    ];

    return (
        <DataGrid
          {...dataGridProps} 
          columns={columns} 
          autoHeight 
        />
    )
}

export default Table;
Войти в полноэкранный режим Выйти из полноэкранного режима

Важно отметить, что в приведенном выше примере мы не передаем свойство rows компоненту <DataGrid/>. Это происходит потому, что переменная dataGridProps автоматически вводит значения rows в компонент <DataGrid> через собственный компонент <Refine/> dataProvider, доступный в файле src/App.tsx вашего приложения refine.

Свойство dataProvider используется для чтения данных из конечной точки API, а затем делает эти данные доступными во всем приложении.

Подробную информацию об использовании см. в документации по провайдеру данных refine.

Рендеринг данных с помощью компонента <DataGrid/>

В качестве источника данных для компонента DataGrid мы будем использовать имитатор API, который мы создали с помощью Mockaroo и My JSON Server.

Для начала создайте папку в папке pages с именем employees, а затем в этой папке создайте файл employees.tsx.

Добавьте следующий код в файл employees.tsx:

 // src/pages/employees.tsx

import React from 'react';
import { useDataGrid, DataGrid, GridColumns, List } from '@pankod/refine-mui';

const EmployeeList: React.FC = () => {
    const { dataGridProps } = useDataGrid();

    const columns = React.useMemo<GridColumns>(
        () => [
            { field: 'id', headerName: 'ID', Width: 30 },
            {
                field: 'full_name',
                headerName: 'Full Name',
                minWidth: 150,
                flex: 1,
                valueGetter: (params) =>
                    `${params.row.first_name || ''} ${
                        params.row.last_name || ''
                    }`,
            },
            {
                field: 'email',
                headerName: 'Email',
                minWidth: 250,
            },
            {
                field: 'department',
                headerName: 'Department',
                minWidth: 150,
            },
            {
                field: 'role',
                headerName: 'Role',
                minWidth: 150,
            },
            {
                field: 'level',
                headerName: 'Level',
                Width: 30,
            },
        ],
        []
    );

    return (
        <List>
            <DataGrid
                {...dataGridProps}
                checkboxSelection
                disableSelectionOnClick
                columns={columns}
                autoHeight
            />
        </List>
    );
};

export default EmployeeList;
Войти в полноэкранный режим Выйти из полноэкранного режима

Давайте разберемся, что происходит выше.

Переменная columns определяет поля столбцов для наших данных. Мы также обернули поля в компонент высшего порядка React.Memo для мемоизации значений, а затем создали поля для каждого свойства из конечной точки нашего ресурса. Мы также использовали атрибут valueGetter для составления значения из двух разных полей.

Далее отредактируйте App.tsx в папке src следующим образом:

// src/App.tsx

import { Refine } from '@pankod/refine-core';
import {
    CssBaseline,
    GlobalStyles,
    ThemeProvider,
    LightTheme,
} from '@pankod/refine-mui';
import routerProvider from '@pankod/refine-react-router-v6';
import dataProvider from '@pankod/refine-simple-rest';
import Layout from './components/Layout';
import EmployeeList from './pages/employees';

function App() {
    return (
        <ThemeProvider theme={LightTheme}>
            <CssBaseline />
            <GlobalStyles styles={{ html: { WebkitFontSmoothing: 'auto' } }} />
            <Refine
                Layout={Layout}
                routerProvider={routerProvider}
                dataProvider={dataProvider(
                    'https://my-json-server.typicode.com/Mich45/employee-data'
                )}
                resources={[{ name: 'employees', list: EmployeeList }]}
            />
        </ThemeProvider>
    );
}

export default App;
Вход в полноэкранный режим Выйти из полноэкранного режима

Вот описание того, что происходит выше:

Родной компонент <Refine/> принимает параметр dataProvider, который определяет источник наших данных (фальшивый REST API, который мы создали ранее), и параметр resources, который принимает массив свойств объекта:

  • Свойство name является именем ресурса, который мы ожидаем получить от REST API — это значение должно соответствовать ресурсу, который мы создали в REST API. В нашем случае employees.
  • Свойство list принимает компонент страницы для отображения данных. Это компонент EmployeeList, который мы импортируем из папки pages/employees.

Мы также добавили компонент макета (Layout.tsx) в папку Layout. Это нужно для того, чтобы настроить внешний вид нашего приложения.

Теперь, если вы перейдете по адресу localhost:8000/employees, вы должны увидеть следующее:

Вуаля! Мы успешно отобразили наши данные из REST API в компоненте MUI DataGrid. В следующем разделе мы рассмотрим, как можно использовать хук useDataGrid для упрощения таких операций, как пагинация, сортировка и фильтрация.

Пагинация, фильтрация и сортировка с помощью хука useDataGrid

Хук useDataGrid упрощает такие операции, как пагинация, сортировка и фильтрация на компоненте <DataGrid/> с помощью гибкого API. В этой части мы воспользуемся хуком для добавления функций пагинации, сортировки и фильтрации к данным таблицы сотрудников.

Пагинация

Пагинация позволяет нам отображать определенное количество строк в DataGrid за один раз и включена по умолчанию. Ее также нельзя отключить. Она доступна в нижней части компонента DataGrid, как показано ниже:

Например, наш список сотрудников имеет в общей сложности 28 строк, но мы можем захотеть отображать только 10 строк на странице. Вот демонстрация, показывающая, как мы можем отобразить 10 рядов элементов на начальной странице с помощью свойства initialPageSize (по умолчанию 25).

Это похоже на использование свойства initialState в компоненте DataGrid. Мы также можем определить, сколько строк пользователь может выбрать для просмотра на странице, используя свойство rowsPerPageOptions.

Обновите employees.tsx с помощью следующих кодов:

// src/pages/employees.tsx

import React from 'react';
import { useDataGrid, DataGrid, GridColumns, List } from '@pankod/refine-mui';

   ...

// ====>
const { dataGridProps } = useDataGrid({initialPageSize: 10});
    const {
        pageSize,
        onPageSizeChange,
        ...restDataGridProps
    } = dataGridProps;
 // <====

    ...

return (
        <List>
        // ====>
            <DataGrid
                {...restDataGridProps}
                checkboxSelection
                disableSelectionOnClick
                columns={columns}
                pageSize={10}
                onPageSizeChange={onPageSizeChange}
                rowsPerPageOptions={[10, 15]}
                autoHeight
            />
            // <====
        </List>
    );

export default EmployeeList;
Вход в полноэкранный режим Выйти из полноэкранного режима

В результате наша сетка отобразится вот так:

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

Сортировка

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

Мы можем сортировать строки в трех порядках: по возрастанию (ASC), по убыванию (DESC) или в нулевом порядке (сортировка будет отключена).

Чтобы отсортировать строки, щелкните или наведите курсор на заголовок любого столбца, при этом появится стрелка, указывающая вверх или вниз в зависимости от порядка сортировки. При сортировке по возрастанию стрелка направлена вверх, а при сортировке по убыванию — вниз. Также можно воспользоваться меню столбцов сетки.

Начальный порядок сортировки

Мы можем инициализировать порядок сортировки для каждого или всех полей в сетке с помощью свойства intialSorter компонента useDataGrid. Это позволит нам сортировать строки при первоначальном отображении страницы.

// src/pages/employees.tsx

const { dataGridProps } = useDataGrid({initialSorter: [{ field: 'level', order: 'desc' }]});
Вход в полноэкранный режим Выход из полноэкранного режима

Приведенный выше пример отсортирует строки с помощью столбца level на начальном рендере в порядке убывания следующим образом:

Управляемая сортировка

Мы также можем сортировать строки извне, используя функцию setSorter из хука useDataGrid. Следующий код показывает, как мы можем сортировать строки, нажимая на пользовательские кнопки вне компонента DataGrid.

// src/pages/employees.tsx

import React from 'react';
import styled from 'styled-components';
import {
    useDataGrid,
    DataGrid,
    GridColumns,
    List,
     // ====>
    Button,
    ButtonGroup,
     // <====
} from '@pankod/refine-mui';

 // ====>
const ButtonsWrapper = styled.div`
    width: 100%;
    margin: 20px 0;
`;
// <====

const EmployeeList: React.FC = () => {
    // ====>
    const { dataGridProps, setSorter } = useDataGrid();
    // <====

    const columns = React.useMemo<GridColumns>(
        () => [
            { field: 'id', headerName: 'ID', Width: 30 },
            {
                field: 'full_name',
                headerName: 'Full Name',
                minWidth: 150,
                flex: 1,
                valueGetter: (params) =>
                    `${params.row.first_name || ''} ${
                        params.row.last_name || ''
                    }`,
            },
            {
                field: 'email',
                headerName: 'Email',
                minWidth: 250,
            },
            {
                field: 'department',
                headerName: 'Department',
                minWidth: 150,
            },
            {
                field: 'role',
                headerName: 'Role',
                minWidth: 150,
            },
            {
                field: 'level',
                headerName: 'Level',
                Width: 30,
            },
        ],
        []
    );

     // ====>
    const handleSorting = (order: 'asc' | 'desc') => {
        setSorter([
            {
                field: 'level',
                order,
            },
        ]);
    };
     // <====

    return (
        <List>
           // ====>
            <ButtonsWrapper>
                <ButtonGroup variant="outlined">
                    <Button onClick={() => handleSorting('asc')}>Asc</Button>
                    <Button onClick={() => handleSorting('desc')}>Desc</Button>
                </ButtonGroup>
            </ButtonsWrapper>
            <DataGrid
                {...dataGridProps}
                checkboxSelection
                columns={columns}
                autoHeight
            />
             // <====
        </List>
    );
};

export default EmployeeList;
Вход в полноэкранный режим Выход из полноэкранного режима

Вот GIF, показывающий результат приведенного выше примера.

Для получения более подробной информации об этой функции обратитесь к документации по сортировке.

Фильтрация

Фильтрация позволяет нам искать значения в строках компонента DataGrid на основе одного критерия за раз.

Мы можем получить доступ к функции сортировки, щелкнув на пункте фильтра в меню столбца:

или с помощью кнопки фильтра на панели инструментов сетки:

Вы можете импортировать компонент GridToolbar и использовать его следующим образом:

// src/pages/employees.tsx

import { GridToolbar } from "@pankod/refine-mui"

<DataGrid
  {...dataGridProps} 
  checkboxSelection
  columns={columns}
  components={{ Toolbar: GridToolbar }} 
  autoHeight 
/>
Войти в полноэкранный режим Выйти из полноэкранного режима

Функция фильтрации работает путем поиска в строках значений, соответствующих заданному оператору фильтрации. Список операторов, которые можно использовать в модели sortModel, можно найти здесь.

Например, в нашей таблице сотрудников мы можем отфильтровать столбец отдел для строк, содержащих значение Support, используя любой из вышеперечисленных методов.

Вот код для приведенного выше примера. Обновите файл employees.tsx с выделенным кодом.

// src/pages/employees.tsx

import React from 'react';
import {
    useDataGrid,
    DataGrid,
    GridColumns,
    List,
    //highlight-next-line
    GridToolbar,
} from '@pankod/refine-mui';

// ====>
const { dataGridProps} = useDataGrid();
// <====

... 

// ====>
const {
    filterMode,
    filterModel,
    onFilterModelChange,
    ...restDataGridProps
} = dataGridProps;
// <====


return (
        <List>
        // ====>
            <DataGrid
                {...restDataGridProps}
                filterMode={filterMode}
                filterModel={filterModel}
                onFilterModelChange={onFilterModelChange}
                columns={columns}
                components={{ Toolbar: GridToolbar }}
                autoHeight
            />
            // <====
        </List>
    );

export default EmployeeList;
Вход в полноэкранный режим Выход из полноэкранного режима

Управляемая фильтрация

Мы также можем выбрать внешнюю фильтрацию таблицы, используя функцию setFilters хука useDataGrid для установки состояния фильтра. Функция принимает три свойства для фильтрации таблицы.

Вот пример, показывающий, как мы можем использовать пользовательский флажок для поиска строк для сотрудников с ролью, равной Рекрутер.

Обновите employees.tsx с выделенным кодом:

// src/pages/employees.tsx

import React from 'react';
import {
    useDataGrid,
    DataGrid,
    GridColumns,
    List,
    GridToolbar,
    // ====>
    FormControlLabel,
    Checkbox,
    // <====
} from '@pankod/refine-mui';

const EmployeeList: React.FC = () => {
    const { dataGridProps, setFilters } = useDataGrid();

    const columns = React.useMemo<GridColumns>(
        () => [
            { field: 'id', headerName: 'ID', Width: 30 },
            {
                field: 'full_name',
                headerName: 'Full Name',
                minWidth: 150,
                flex: 1,
                valueGetter: (params) =>
                    `${params.row.first_name || ''} ${
                        params.row.last_name || ''
                    }`,
            },
            {
                field: 'email',
                headerName: 'Email',
                minWidth: 250,
            },
            {
                field: 'department',
                headerName: 'Department',
                minWidth: 150,
            },
            {
                field: 'role',
                headerName: 'Role',
                minWidth: 150,
            },
            {
                field: 'level',
                headerName: 'Level',
                Width: 30,
            },
        ],
        []
    );
    const {
        filterMode,
        filterModel,
        onFilterModelChange,
        ...restDataGridProps
    } = dataGridProps;

   // ====>
    const handleFilter = (
        e: React.ChangeEvent<HTMLInputElement>,
        checked: boolean
    ) => {
        setFilters([
            {
                field: 'role',
                value: checked ? 'Recruiter' : undefined,
                operator: 'eq',
            },
        ]);
    };

   // <====
    return (
        <List>
            // ====>
            <FormControlLabel
                label="Filter Employees with Recruiter Role"
                control={<Checkbox onChange={handleFilter} />}
            />
            // <====
            <DataGrid
                {...restDataGridProps}
                filterMode={filterMode}
                filterModel={filterModel}
                onFilterModelChange={onFilterModelChange}
                columns={columns}
                components={{ Toolbar: GridToolbar }}
                autoHeight
            />
        </List>
    );
};
export default EmployeeList;
Войдите в полноэкранный режим Выйти из полноэкранного режима

Что дает следующий результат при нажатии на флажок:

Обратитесь к документации по фильтрации для получения дополнительной информации о доступных настройках и расширенном использовании.

Заключение

В этой статье мы познакомили вас с компонентом MUI <DataGrid/> и как использовать его для отображения табличных данных. Мы также узнали, как упростить такие операции, как пагинация, сортировка и фильтрация на компоненте с помощью хука useDataGrid.

Надеемся, что эта статья поможет вам начать работу с компонентом <DataGrid/> в ваших приложениях refine.

Что делать дальше? Посмотрите документацию по хуку useDataGrid здесь и документацию по MUI X <DataGrid/> для получения дополнительной информации об использовании и справки.

Автор: Майкл Хунгбо

Живой пример StackBlitz

Создавайте CRUD-приложения на основе React без ограничений

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

Ознакомьтесь с refine, если вы заинтересованы в безголовом фреймворке с надежной архитектурой и полным набором лучших отраслевых практик для вашего следующего CRUD-проекта.

refine — это фреймворк на базе React с открытым исходным кодом для создания CRUD-приложений без ограничений.
Он может ускорить время разработки до 3 раз без ущерба для свободы стиля, кастомизации и рабочего процесса проекта.

refine является безголовым по своей конструкции и подключает 30+ бэкенд-сервисов «из коробки», включая пользовательские REST и GraphQL API.

Посетите GitHub-репозиторий refine для получения дополнительной информации, демонстраций, учебников и примеров проектов.

Оцените статью
devanswers.ru
Добавить комментарий