如何寫好一個React table component


最近上手做一個公司項目,前端用React, 所以為了減少冗余代碼,對組件的復用率要求很高,這不需要一個React table component

為了實現當前的業務需求小編很快寫了第一個component

       分析:table分為兩個部分header和body,header是固定的,而body的列數固定,但是行數不固定。對於data,也就是table的body,是一個對象數組,每一個對象就是table的一行,對象的屬性名稱也是固定的。根據上述分析結果,我寫了下面這個component。

1.第一個table component

 先上代碼:

import React from 'react' import PropTypes from 'prop-types' import { Table } from 'react-bootstrap' import { RowHead } from './style' const TableHeader = props => { const { data, headerFormatter } = props return ( <thead>
            <RowHead> {data && data.map(item => <th key={item}> {headerFormatter ? headerFormatter(item) : item}</th>)}
            </RowHead>

        </thead>
 ) } TableHeader.propTypes = { data: PropTypes.arrayOf(PropTypes.string).isRequired, headerFormatter: PropTypes.func.isRequired, } const TableColumns = props => { const { data, columnNames, formatter } = props return ( <tdoby> {data && columnNames && data.map(item => ( <tr key={item.id}> {columnNames.map(key => ( <td key={item.id}>{formatter(key, item[key], item.id)}</td>
 ))} </tr>
 ))} </tdoby>
 ) } TableColumns.propTypes = { data: PropTypes.arrayOf(PropTypes.object).isRequired, columnNames: PropTypes.arrayOf(PropTypes.string).isRequired, formatter: PropTypes.func.isRequired, } const TableContainer = ({ data, headers, columnNames, formatter, headerFormatter }) => ( <Table responsive>
        <TableHead data={header} headerFormatter={headerFormatter} />
        <TableColumns data={data} columnNames={columnNames} formatter={formatter} />
    </Table>
) TableContainer.propTypes = { headers: PropTypes.arrayOf(PropTypes.string).isRequired, headerFormatter: PropTypes.func.isRequired, columnNames: PropTypes.arrayOf(PropTypes.string).isRequired, formatter: PropTypes.func.isRequired, data: PropTypes.arrayOf(PropTypes.object).isRequired, } export default TableContainer

      總結: 

       細心的同學不難發現,首先有許多重復的代碼, TableContainer.propTypes TableHeader.propTypes  TableColumns.propTypes

       對於header,如果這么寫,header就顯示同樣的format,不能實現對表頭每一個名稱進行個性化的定制。

       body同樣的道理,使所有的行得每個元素都具有相同的format,或者在使用此component時,需要進行大量的判斷,根據不同的字段,賦予不同的format。這種component簡直有同於無。 

       很明顯,不改進,codeReview肯定過不了。

2.第二個react table component 

import React from 'react' import PropTypes from 'prop-types' import { Table } from 'react-bootstrap' import { RowHead } from './style' const HeaderCell = props => { const { header, headerFormatter } = props return <th> {headerFormatter ? headerFormatter(header) : header} </th>
} const HeaderCellPropTypes = { header: PropTypes.arrayOf(PropTypes.string).isRequired, headerFormatter: PropTypes.oneOfType([PropTypes.func, PropTypes.element]).isRequired, } HeaderCell.propTypes = HeaderCellPropTypes const ColumnCell = props => { const { value, formatter, coluumnId } = props return <td> {formatter ? formatter(value, coluumnId) : value}</td>
} ColumnCell.propTypes = { value: PropTypes.string.isRequired, formatter: PropTypes.oneOfType([PropTypes.func, PropTypes.element]).isRequired, coluumnId: PropTypes.string.isRequired, } const TableContainer = ({ cloumns, data }) => ( <Table responsive>
        <thead>
            <RowHead> {cloumns && cloumns.map(item => ( <HeaderCell key={item.header} header={item.header} headerFormatter={item.headerFormatter} />
 ))} </RowHead>
        </thead>
        <tbody> {data && cloumns && data.map(item => ( <tr key={item.id}> {cloumns.map(cell => ( <ColumnCell key={item.id} coluumnId={item.id} formatter={item.formatter} value={item[cell.accessor]} />
 ))} </tr>
 ))} </tbody>
    </Table>
) TableContainer.propTypes = { cloumns: PropTypes.arrayOf( PropTypes.shape({ ...HeaderCellPropTypes, accessor: PropTypes.oneOf(PropTypes.func, PropTypes.string), formatter: PropTypes.oneOfType([PropTypes.func, PropTypes.element]).isRequired, }) ).isRequired, data: PropTypes.arrayOf(PropTypes.object).isRequired,
}

分析: 第一個Component的所有的不足,在第二個component中變成了優勢。good

export default ReactTableComponent

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM