耶! ?您已經完成了這個由兩部分組成的系列的最後一部分!如果您還沒有查看第 1 部分,請先在此停下來並完成第 1 部分。別擔心,我們會等你回來! ?
在第 1 部分中,我們建立了 CustomTable 元件。您可以在這裡看到它的實際效果。
在第二部分中,我們將擴展該組件以添加一些新功能。以下是我們將要努力的目標:
為了支援這一點,CustomTable 元件將需要一些增強功能:
讓我們深入建立第一個功能。
我們將首先在 Column 介面中新增一個格式方法來控制特定列如何呈現其值。
interface Column<T> { id: keyof T; label: string; format?: (value: string | number) => string; }
此可選格式方法將在必要時用於格式化資料。讓我們透過 Country.tsx 檔案中的範例來看看它是如何運作的。我們將向人口列新增格式方法。
const columns: Column<Country>[] = [ { id: "name", label: "Name" }, { id: "code", label: "ISO\u00a0Code" }, { id: "population", label: "Population", format: (value) => new Intl.NumberFormat("en-US").format(value as number), }, { id: "size", label: "Size\u00a0(km\u00b2)", }, { id: "density", label: "Density", }, ];
在這裡,我們使用 JavaScript Intl.NumberFormat 方法將人口格式設為數字。您可以在這裡了解有關此方法的更多資訊。
接下來,我們需要更新 CustomTable 元件以檢查格式函數並在存在時套用它。
<TableBody> {rows.map((row, index) => ( <TableRow hover tabIndex={-1} key={index}> {columns.map((column, index) => ( <TableCell key={index}> {column.format ? column.format(row[column.id] as string) : (row[column.id] as string)} </TableCell> ))} </TableRow> ))} </TableBody>
透過此修改,人口列現在以適當的格式呈現。您可以在這裡看到它的實際效果。
現在,讓我們實作下一個功能:允許自訂範本來呈現列。為此,我們將添加對將 JSX 作為子屬性傳遞或使用渲染屬性的支持,讓消費者完全控制每個單元格的渲染方式。
首先,我們將擴展 Props 介面以包含可選的子屬性。
interface Props<T> { rows: T[]; columns: Column<T>[]; children?: (row: T, column: Column<T>) => React.ReactNode; }
接下來,我們將修改 CustomTable 元件以支援這個新道具,同時保留現有行為。
<TableRow> {columns.map((column, index) => ( <TableCell key={index}> {children ? children(row, column) : column.format ? column.format(row[column.id] as string) : row[column.id]} </TableCell> ))} </TableRow>
這確保瞭如果傳遞了children 屬性,則使用自訂模板;否則,我們會回到預設行為。
讓我們也重構程式碼以使其更可重複使用:
const getFormattedValue = (column, row) => { const value = row[column.id]; return column.format ? column.format(value) : value as string; }; const getRowTemplate = (row, column, children) => { return children ? children(row, column) : getFormattedValue(column, row); };
現在讓我們在 Country.tsx 檔案中建立一個自訂行元件。我們將建立一個 CustomRow 元件來處理特殊的渲染邏輯。
interface RowProps { row: Country; column: Column<Country>; } const CustomRow = ({ row, column }: RowProps) => { const value = row[column.id]; if (column.format) { return <span>{column.format(value as string)}</span>; } return <span>{value}</span>; };
然後,我們將更新 Country.tsx 以將此 CustomRow 元件傳遞給 CustomTable。
const Countries = () => ( <CustomTable columns={columns} rows={rows}> {(row, column) => <CustomRow column={column} row={row} />} </CustomTable> );
對於 People.tsx,它不需要任何特殊的模板,我們可以簡單地渲染表格,而不需要 Children 屬性。
const People = () => <CustomTable columns={columns} rows={rows} />;
我們可以做出的改進是使用陣列索引作為鍵,這可能會導致問題。相反,讓我們強制每行使用唯一的 rowKey。
我們將擴展 Props 介面以需要 rowKey。
interface Props<T> { rowKey: keyof T; rows: T[]; columns: Column<T>[]; children?: (row: T, column: Column<T>) => React.JSX.Element | string; onRowClick?: (row: T) => void; }
現在CustomTable的每個消費者都必須提供rowKey來確保穩定渲染。
<CustomTable rowKey="code" rows={rows} onRowClick={handleRowClick} columns={columns} > {(row, column) => <CustomRow column={column} row={row} />} </CustomTable>
在此處查看完整程式碼。
在本文中,我們透過新增格式選項和傳遞列的自訂範本的功能來擴充自訂 CustomTable 元件。這些功能使我們能夠更好地控制資料在表中的呈現方式,同時也使元件靈活且可重用於不同的用例。
我們也透過強制執行 rowKey 屬性來改進元件,以避免使用陣列索引作為鍵,從而確保更有效率和穩定的渲染。
我希望這份指南對您有幫助!歡迎在留言區分享你的想法。
感謝您一路陪伴我! ?
以上是如何使用 React 和 Typescript 建立自訂表格元件(第 2 部分)的詳細內容。更多資訊請關注PHP中文網其他相關文章!