This renders the header properly in that I can see a table with a "Product ID" header for the column:
// DataTable.tsx
// React Imports
import React, { useState } from 'react';
// PrimeReact Imports
import { DataTable as DT } from 'primereact/datatable';
import { Column } from 'primereact/column';
// Custom Imports
import DataTableHeader from './DataTableHeader';
const DataTable = (): JSX.Element => {
const [rowData, setRowData] = useState([]);
return (
<DT
value={rowData}
emptyMessage='Run the utility first.'
size='small'
>
<Column field='product_id' header='Product ID' />
</DT>
);
};
export default DataTable;
I'm trying to refactor it so I can reuse <DataTable />
and <Column />
given they are almost identical throughout the app:
// DataTable.tsx
// React Imports
import React, { useState } from 'react';
// PrimeReact Imports
import { DataTable as DT } from 'primereact/datatable';
// Custom Imports
import DataTableHeader from './DataTableHeader';
import ColumnProductID from './ColumnProductID';
const DataTable = (): JSX.Element => {
const [rowData, setRowData] = useState([]);
return (
<DT
value={rowData}
emptyMessage='Run the utility first.'
size='small'
>
<ColumnProductID />
</DT>
);
};
export default DataTable;
// ColumnProductID.tsx
import React from 'react';
// PrimeReact Imports
import { Column } from 'primereact/column';
const ColumnProductID = (): JSX.Element => {
return <Column field='product_id' header='Product ID' />
};
export default ColumnProductID;
In this case, the <Column />
header is not rendered... inspecting the page elements for an occurrence of "Product ID" does not yield anything so it seems the <ColumnProductID />
is not being rendered.
Suggestions for what I am doing wrong here?
I did manage to get this to work, by doing:
// DataTable.tsx
// React Imports
import React, { useState } from 'react';
// PrimeReact Imports
import { DataTable as DT } from 'primereact/datatable';
// Custom Imports
import DataTableHeader from './DataTableHeader';
import ColumnProductID from './ColumnProductID';
const DataTable = (): JSX.Element => {
const [rowData, setRowData] = useState([]);
return (
<DT
value={rowData}
emptyMessage='Run the utility first.'
size='small'
>
<ColumnProductID field='product_id' header='Product ID' />
</DT>
);
};
export default DataTable;
// ColumnProductID.tsx
import React from 'react';
// PrimeReact Imports
import { Column } from 'primereact/column';
interface ColumnProductIDProps {
field: string;
header: string;
}
const ColumnProductID = (props: ColumnProductIDProps): JSX.Element => {
return <Column field={field} header={header} />
};
export default ColumnProductID;
But this is undesirable... in fact it is the very thing I'm trying to avoid and it is pointless to refactor <Column />
from primereact
into a <ColumnProductID />
component. This effectively makes <ColumnProductID /> === <Column />
with an additional layer and unnecessary complexity.
The redundancy I'm trying to get around is this:
status
, for example, can relate to all kinds of data: Customers, Companies, Products, Leads, etc. etc. etc.<DataTable />
this field status
appears in, it should have the exact same props.<DataTable />
for Customers, Companies, Products, Leads, and this <Column field='status' />
is in all of them, and you want to change something about it, then you have to go into each <DataTable />
and update it.<ColumnStatus />
component and pass that into the <DataTable />
then you only need to update it one place: in the <ColumnStatus />
component.This is not currently possible with PrimeReact. Column is not a a "component" that renders itself so it cannot be wrapped or extended. The Datatable looks specifically for <Column>
as children and not anything else.
See: https://github.com/primefaces/primereact/issues/2268
See: https://github.com/primefaces/primereact/issues/2052#issuecomment-1173678665