From 5383d4dd5e41bc421f6ed0f09af91b1267347f5b Mon Sep 17 00:00:00 2001 From: afc163 Date: Mon, 1 Aug 2016 19:06:47 +0800 Subject: [PATCH] split TableCell for better perfermance --- src/ExpandIcon.jsx | 16 +++++ src/TableCell.jsx | 90 +++++++++++++++++++++++++++++ src/TableRow.jsx | 141 ++++++++++++++++----------------------------- 3 files changed, 157 insertions(+), 90 deletions(-) create mode 100644 src/ExpandIcon.jsx create mode 100644 src/TableCell.jsx diff --git a/src/ExpandIcon.jsx b/src/ExpandIcon.jsx new file mode 100644 index 000000000..16f8f041a --- /dev/null +++ b/src/ExpandIcon.jsx @@ -0,0 +1,16 @@ +import React from 'react'; + +export default ({ expandable, prefixCls, onExpand, needIndentSpaced, expanded, record }) => { + if (expandable) { + const expandClassName = expanded ? 'expanded' : 'collapsed'; + return ( + onExpand(!expanded, record)} + /> + ); + } else if (needIndentSpaced) { + return ; + } + return null; +}; diff --git a/src/TableCell.jsx b/src/TableCell.jsx new file mode 100644 index 000000000..1dd19f90d --- /dev/null +++ b/src/TableCell.jsx @@ -0,0 +1,90 @@ +import React, { PropTypes } from 'react'; +import objectPath from 'object-path'; +import shallowequal from 'shallowequal'; +import ExpandIcon from './ExpandIcon'; + +const TableCell = React.createClass({ + propTypes: { + record: PropTypes.object, + prefixCls: PropTypes.string, + isColumnHaveExpandIcon: PropTypes.bool, + index: PropTypes.number, + expanded: PropTypes.bool, + expandable: PropTypes.any, + onExpand: PropTypes.func, + needIndentSpaced: PropTypes.bool, + className: PropTypes.string, + indent: PropTypes.number, + indentSize: PropTypes.number, + expandIconAsCell: PropTypes.bool, + dataIndex: PropTypes.string, + render: PropTypes.func, + }, + shouldComponentUpdate(nextProps) { + return !shallowequal(nextProps, this.props); + }, + isInvalidRenderCellText(text) { + return text && !React.isValidElement(text) && + Object.prototype.toString.call(text) === '[object Object]'; + }, + render() { + const { className, dataIndex, render, record, indentSize, prefixCls, indent, + isColumnHaveExpandIcon, index, expandable, onExpand, needIndentSpaced, + expanded } = this.props; + + let text = objectPath.get(record, dataIndex); + let tdProps; + let colSpan; + let rowSpan; + + if (render) { + text = render(text, record, index); + if (this.isInvalidRenderCellText(text)) { + tdProps = text.props || {}; + rowSpan = tdProps.rowSpan; + colSpan = tdProps.colSpan; + text = text.children; + } + } + + // Fix https://github.com/ant-design/ant-design/issues/1202 + if (this.isInvalidRenderCellText(text)) { + text = null; + } + + const expandIcon = ( + + ); + + const indentText = ( + + ); + + if (rowSpan === 0 || colSpan === 0) { + return null; + } + return ( + + {isColumnHaveExpandIcon ? indentText : null} + {isColumnHaveExpandIcon ? expandIcon : null} + {text} + + ); + }, +}); + +export default TableCell; diff --git a/src/TableRow.jsx b/src/TableRow.jsx index 8bc601f1d..458779357 100644 --- a/src/TableRow.jsx +++ b/src/TableRow.jsx @@ -1,5 +1,7 @@ import React, { PropTypes } from 'react'; -import objectPath from 'object-path'; +import shallowequal from 'shallowequal'; +import TableCell from './TableCell'; +import ExpandIcon from './ExpandIcon'; const TableRow = React.createClass({ propTypes: { @@ -9,6 +11,19 @@ const TableRow = React.createClass({ prefixCls: PropTypes.string, expandIconColumnIndex: PropTypes.number, onHover: PropTypes.func, + columns: PropTypes.array, + style: PropTypes.object, + visible: PropTypes.bool, + index: PropTypes.number, + hoverKey: PropTypes.any, + expanded: PropTypes.bool, + expandable: PropTypes.any, + onExpand: PropTypes.func, + needIndentSpaced: PropTypes.bool, + className: PropTypes.string, + indent: PropTypes.number, + indentSize: PropTypes.number, + expandIconAsCell: PropTypes.bool, }, getDefaultProps() { @@ -20,119 +35,65 @@ const TableRow = React.createClass({ }; }, - componentWillUnmount() { - this.props.onDestroy(this.props.record); + shouldComponentUpdate(nextProps) { + return !shallowequal(nextProps, this.props); }, - isInvalidRenderCellText(text) { - return text && !React.isValidElement(text) && - Object.prototype.toString.call(text) === '[object Object]'; + componentWillUnmount() { + this.props.onDestroy(this.props.record); }, render() { - const props = this.props; - const prefixCls = props.prefixCls; - const columns = props.columns; - const record = props.record; - const style = props.style; - const visible = props.visible; - const index = props.index; - const hoverKey = props.hoverKey; + const { + prefixCls, columns, record, style, visible, index, hoverKey, + expandIconColumnIndex, expandIconAsCell, onRowClick, onHover, expanded, + expandable, onExpand, needIndentSpaced, className, indent, indentSize, + } = this.props; + const cells = []; - const expanded = props.expanded; - const expandable = props.expandable; - const expandIconAsCell = props.expandIconAsCell; - const indent = props.indent; - const indentSize = props.indentSize; - const needIndentSpaced = props.needIndentSpaced; - const onRowClick = props.onRowClick; - const expandIconColumnIndex = props.expandIconColumnIndex; for (let i = 0; i < columns.length; i++) { - const col = columns[i]; - const colClassName = col.className || ''; - const render = col.render; - let text = objectPath.get(record, col.dataIndex); - - let expandIcon; - let tdProps; - let colSpan; - let rowSpan; - let notRender = false; - - if (expandable) { - const expandClassName = expanded ? 'expanded' : 'collapsed'; - expandIcon = ( - - ); - } else if (needIndentSpaced) { - expandIcon = ; - } - - const isColumnHaveExpandIcon = expandIconAsCell ? false : (i === expandIconColumnIndex); - if (expandIconAsCell && i === 0) { cells.push( - {expandIcon} + ); } - - if (render) { - text = render(text, record, index); - if (this.isInvalidRenderCellText(text)) { - tdProps = text.props || {}; - rowSpan = tdProps.rowSpan; - colSpan = tdProps.colSpan; - text = text.children; - } - } - - // Fix https://github.com/ant-design/ant-design/issues/1202 - if (this.isInvalidRenderCellText(text)) { - text = null; - } - - if (rowSpan === 0 || colSpan === 0) { - notRender = true; - } - - const indentText = ( - ); - - if (!notRender) { - cells.push( - - {isColumnHaveExpandIcon ? indentText : null} - {isColumnHaveExpandIcon ? expandIcon : null} - {text} - - ); - } } return ( {cells}