import { Component, isValidElement } from 'react'; import classnames from 'classnames'; import { GridColumnContext } from './ColumnContext'; import { IGridInnerColumn } from './Grid'; import { IGridCellPos } from './types'; import isNil from '../utils/isNil'; import getFromPath from '../utils/getFromPath'; import { hasOwnProperty } from '../utils/hasOwn'; interface IGridCellProps { column: IGridInnerColumn; data: Data; pos: IGridCellPos; columnIndex: number; prefix: string; } class Cell extends Component> { isInvalidRenderCellText(text: any) { return ( text && !isValidElement(text) && Object.prototype.toString.call(text) === '[object Object]' ); } getText = (props: IGridCellProps) => { return props.data?.[`${props.column?.name}`]; }; onClick: React.MouseEventHandler = e => { const { data, column: { onCellClick }, } = this.props; if (typeof onCellClick === 'function') { onCellClick(data, e); } }; shouldComponentUpdate(nextProps: IGridCellProps) { // 如果存在 bodyRender 属性则 render if (nextProps.column && hasOwnProperty(nextProps.column, 'bodyRender')) { return true; } // 如果不存在 bodyRender 则比较 name 对应的值是否一致 return this.getText(this.props) !== this.getText(nextProps); } static contextType = GridColumnContext; render() { const { prefix, column, data, pos } = this.props; const { isValueEmpty: isValueEmptyInCtx, defaultText: defaultTextInCtx } = this.context; const { name, width, bodyRender, textAlign, nowrap, noWrap, className, defaultText = defaultTextInCtx, isValueEmpty = isValueEmptyInCtx ?? isNil, } = column; let text: any = getFromPath(data, name); if (isValueEmpty(text) && !isNil(defaultText)) { text = defaultText; } let tdProps; let colSpan; let rowSpan; if (typeof bodyRender === 'function') { text = bodyRender(data, pos, name); if (this.isInvalidRenderCellText(text)) { tdProps = text.props || {}; colSpan = tdProps.colSpan; rowSpan = tdProps.rowSpan; text = text.children; } } if (this.isInvalidRenderCellText(text)) { text = null; } if (rowSpan === 0 || colSpan === 0) { return null; } return ( 1, [`${prefix}-grid-td-selection`]: ['selection-column', 'selection-column-single'].indexOf( column.key ) !== -1, [`${prefix}-grid-td-expand`]: column.key === 'expand-column', [`${prefix}-grid-td-break-word`]: typeof width !== undefined, })} {...tdProps} onClick={this.onClick} > {text} ); } } export default Cell;