Одной из сложных вещей, которую должен делать веб-разработчик, является отображение таблиц, в основном потому, что таблица должна быть простой в использовании, я имею в виду обеспечение пагинации, фильтрации, сортировки и всего остального для работы с данными. Иногда добиться этого на настольном компьютере сложно, но выполнимо, но на мобильном это может быть даже немного сложнее, поэтому сейчас я собираюсь поделиться своей оберткой для таблиц, чтобы облегчить эту задачу.
Как вы уже прочитали в заголовке, для создания таблиц нам понадобится React Data Table Component (RDT), который представляет собой мощный пакет, предоставляющий хороший API для сортировки, пагинации, фильтрации, стилизации и многого другого.
Если вы заглянули в документацию по RDT, то, вероятно, заметили, что настройка, позволяющая сделать таблицу мобильно отзывчивой, не предусмотрена, так в чем же смысл этой статьи?
Ну, опция есть, но когда вам нужно добавить кнопки действия, чтобы открыть модальное окно, загрузить файл или что-либо еще, есть большая вероятность, что вам придется повторить код несколько раз, в зависимости от того, сколько таблиц нужно вашему приложению.
Чтобы объяснить, что будет решать эта обертка, я собираюсь предоставить репозиторий и codesandbox со всем используемым кодом.
Установка RDT
- Установите RDT с помощью одной из следующих команд:
npm i react-data-table-component styled-components
yarn react-data-table-component styled-components
const columns = useMemo(() => [
{
name: 'Column name 1',
id: 'columnId1',
selector: ({ attribute1 }) => attribute1
},
{
name: 'Column name 2',
id: 'columnId2',
selector: ({ attribute2 }) => attribute2
},
{
name: 'actions',
id: 'actions',
cell: ({ attribute3 }) => (
<div>
<span onClick={(attribute3) => {}}Action 1</span>
</div>
),
hide: 'md'
}
// more columns...
], [])
Добавив свойство hide: 'md'
, если разрешение окна меньше разрешения рабочего стола, колонка будет автоматически скрыта, это просто, но теперь потребуется способ отображения на мобильных устройствах, и здесь пригодится ExpandedComponent
.
Создание обертки
<ExpandedWrapper>
<Item label="ColumnName">{plainValue}</Item>
<Item label="ColumnName"><span>children</span></Item>
</ExpandedWrapper>
-
Что такое
ExpandedWrapper
иItem
? Оба компонента используются для поддержания согласованности стилей, и вы можете создавать свои собственные компоненты по своему усмотрению:-
ExpandedWrapper
const ExpandedWrapper = ({ children }) => { return ( <div className="grid text-sm mr-4"> {children} </div> ) }
-
Item
const Item = ({ label, children }) => { return ( <div className="flex"> <div className="max-w-max my-2 ml-16 font-semibold"> <span>{label}</span> </div> <div className="max-w-max my-2 ml-4"> <span>{children}</span> </div> </div> ) }
-
В чем проблема?
Ответ на этот вопрос довольно прост, компонент Datatatable
имеет свойство data
и оно автоматически разделяется в расширенном компоненте, но если вам нужно обеспечить функциональность кнопок действий или ссылок, вам нужно создать функцию для настольного представления в «основном компоненте» и мобильную функцию в «расширенном компоненте», поэтому именно здесь React Context
поможет избежать дублирования кода с помощью нескольких отдельных строк кода.
import { createContext } from 'react'
const ExpandedComponentContext = createContext()
const ExpandedComponentProvider = ({ children, ...rest }) => {
return (
<ExpandedComponentContext.Provider value={{ ...rest }}>
{children}
</ExpandedComponentContext.Provider>
)
}
export { ExpandedComponentProvider, ExpandedComponentContext }
import { useContext } from 'react'
import { ExpandedComponentContext } from 'contexts/ExpandedComponentProvider'
const useExpandedComponent = () => {
const context = useContext(ExpandedComponentContext)
if (context === undefined) {
throw new Error(
'useExpandedComponent must be used within a ExpandedComponentProvider'
)
}
return context
}
export default useExpandedComponent
Теперь вы можете обернуть вашу таблицу с помощью ExpandedComponentProvider
, чтобы разделить все функции или реквизиты, которые вы хотите, а затем в расширенном компоненте использовать хук useExpandedComponent
, чтобы получить их все и использовать по своему усмотрению, примечание: expandableRows
— это флаг, который нужно контролировать, когда вы хотите использовать расширенный компонент, например, используя медиа-запрос или функцию для получения ширины окна, например:
import { useCallback, useMemo } from 'react'
import { Table } from 'components/Table'
import { ExpandedComponentProvider } from 'contexts/ExpandedComponentProvider'
import ExpandedExampleComponent from 'components/ExpandedExampleComponent'
const Example = () => {
const data = [
{
attribute1: 'attribute1'
},
{
attribute2: 'attribute2'
},
{
attribute3: 'attribute3'
}
]
const handleClick = useCallback(
(url) => () => {
window.open(url, '_blank', 'noopener,noreferrer,resizable')
}, [])
const columns = useMemo(() => [
{
name: 'Column name 1',
id: 'columnId1',
selector: ({ attribute1 }) => attribute1
},
{
name: 'Column name 2',
id: 'columnId2',
selector: ({ attribute2 }) => attribute2
},
{
name: 'Actions',
id: 'actions',
cell: ({ attribute3 }) => (
<span onClick {handleClick(attribute3)}Action 1</span>
),
hide: 'md'
}
// more columns...
], [])
return (
<ExpandedComponentProvider onClick={handleClick}>
<Table
name="demo"
columns={columns}
data={data || []}
expandableRows
expandableRowsComponent={ExpandedExampleComponent}
// more props...
/>
</ExpandedComponentProvider>
)
}
export default Example
и ExpandedExampleComponent
:
import { Item, ExpandedWrapper } from 'components/Table'
import useExpandedComponent from 'hooks/useExpandedComponent'
const ExpandedExampleComponent = ({ data }) => {
const { onClick } = useExpandedComponent()
const { attribute1, attribute2, attribute3 } = data
return (
<ExpandedWrapper>
<Item label="Column Name 1">{attribute1}</Item>
<Item label="Column Name 2">{attribute2}</Item>
<Item label="Actions">
<span onClick={onClick(attribute3)}Action 1</span>
</Item>
</ExpandedWrapper>
)
}
export default ExpandedExampleComponent
Предварительный просмотр в реальном времени:
Репозиторий: https://github.com/AgusRdz/rdt-context-demo
Заключительные мысли
Как вы можете видеть, вы можете создавать удивительные таблицы с помощью RDT, а в сочетании с React Context вы также можете добавить простой способ работы с ними без особых усилий.
Я надеюсь, что этот небольшой вклад поможет вам сократить время реализации таблиц, для меня было очень легко работать с ними, избегая повторения кода и в то же время упрощая их обслуживание.
Счастливого кодинга!