Skip to content

Commit

Permalink
refactor: Body related component rm useMemo & wrap with `responsiveIm…
Browse files Browse the repository at this point in the history
…mutable` (#923)

* refactor: Body responsive

* refactor: BodyRow responsive

* refactor: Remove duplicate key

* chore: add record of ExpandableRow

* refactor: Rm ExpandedRow memo

* chore: fix lint
  • Loading branch information
zombieJ authored Dec 29, 2022
1 parent 0a49fc2 commit ecf3fdb
Show file tree
Hide file tree
Showing 12 changed files with 179 additions and 150 deletions.
29 changes: 25 additions & 4 deletions src/Body/BodyRow.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useContext } from '@rc-component/context';
import { responseImmutable, useContext } from '@rc-component/context';
import classNames from 'classnames';
import * as React from 'react';
import Cell from '../Cell';
import TableContext from '../context/TableContext';
import devRenderTimes from '../hooks/useRenderTimes';
import type {
ColumnType,
CustomizeComponent,
Expand All @@ -19,7 +20,6 @@ export interface BodyRowProps<RecordType> {
renderIndex: number;
className?: string;
style?: React.CSSProperties;
recordKey: Key;
expandedKeys: Set<Key>;
rowComponent: CustomizeComponent;
cellComponent: CustomizeComponent;
Expand All @@ -35,6 +35,10 @@ export interface BodyRowProps<RecordType> {
function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
props: BodyRowProps<RecordType>,
) {
if (process.env.NODE_ENV !== 'production') {
devRenderTimes(props);
}

const {
className,
style,
Expand Down Expand Up @@ -80,7 +84,24 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
]);
const [expandRended, setExpandRended] = React.useState(false);

const expanded = expandedKeys && expandedKeys.has(props.recordKey);
if (process.env.NODE_ENV !== 'production') {
devRenderTimes({
prefixCls,
fixedInfoList,
flattenColumns,
expandableType,
expandRowByClick,
onTriggerExpand,
rowClassName,
expandedRowClassName,
indentSize,
expandIcon,
expandedRowRender,
expandIconColumnIndex,
});
}

const expanded = expandedKeys && expandedKeys.has(rowKey);

React.useEffect(() => {
if (expanded) {
Expand Down Expand Up @@ -230,4 +251,4 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(

BodyRow.displayName = 'BodyRow';

export default BodyRow;
export default responseImmutable(BodyRow);
91 changes: 42 additions & 49 deletions src/Body/ExpandedRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useContext } from '@rc-component/context';
import * as React from 'react';
import Cell from '../Cell';
import TableContext from '../context/TableContext';
import devRenderTimes from '../hooks/useRenderTimes';
import type { CustomizeComponent } from '../interface';

export interface ExpandedRowProps {
Expand All @@ -15,66 +16,58 @@ export interface ExpandedRowProps {
isEmpty: boolean;
}

function ExpandedRow({
prefixCls,
children,
component: Component,
cellComponent,
className,
expanded,
colSpan,
isEmpty,
}: ExpandedRowProps) {
function ExpandedRow(props: ExpandedRowProps) {
if (process.env.NODE_ENV !== 'production') {
devRenderTimes(props);
}

const {
prefixCls,
children,
component: Component,
cellComponent,
className,
expanded,
colSpan,
isEmpty,
} = props;

const { scrollbarSize, fixHeader, fixColumn, componentWidth, horizonScroll } = useContext(
TableContext,
['scrollbarSize', 'fixHeader', 'fixColumn', 'componentWidth', 'horizonScroll'],
);

// Cache render node
return React.useMemo(() => {
let contentNode = children;

if (isEmpty ? horizonScroll : fixColumn) {
contentNode = (
<div
style={{
width: componentWidth - (fixHeader ? scrollbarSize : 0),
position: 'sticky',
left: 0,
overflow: 'hidden',
}}
className={`${prefixCls}-expanded-row-fixed`}
>
{componentWidth !== 0 && contentNode}
</div>
);
}
let contentNode = children;

return (
<Component
className={className}
if (isEmpty ? horizonScroll : fixColumn) {
contentNode = (
<div
style={{
display: expanded ? null : 'none',
width: componentWidth - (fixHeader ? scrollbarSize : 0),
position: 'sticky',
left: 0,
overflow: 'hidden',
}}
className={`${prefixCls}-expanded-row-fixed`}
>
<Cell component={cellComponent} prefixCls={prefixCls} colSpan={colSpan}>
{contentNode}
</Cell>
</Component>
{componentWidth !== 0 && contentNode}
</div>
);
}, [
children,
Component,
className,
expanded,
colSpan,
isEmpty,
scrollbarSize,
componentWidth,
fixColumn,
fixHeader,
horizonScroll,
]);
}

return (
<Component
className={className}
style={{
display: expanded ? null : 'none',
}}
>
<Cell component={cellComponent} prefixCls={prefixCls} colSpan={colSpan}>
{contentNode}
</Cell>
</Component>
);
}

export default ExpandedRow;
143 changes: 66 additions & 77 deletions src/Body/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { useContext } from '@rc-component/context';
import { responseImmutable, useContext } from '@rc-component/context';
import * as React from 'react';
import type { PerfRecord } from '../context/PerfContext';
import PerfContext from '../context/PerfContext';
import TableContext from '../context/TableContext';
import useFlattenRecords from '../hooks/useFlattenRecords';
import devRenderTimes from '../hooks/useRenderTimes';
import type { GetComponentProps, GetRowKey, Key } from '../interface';
import { getColumnsKey } from '../utils/valueUtil';
import BodyRow from './BodyRow';
Expand All @@ -21,16 +22,22 @@ export interface BodyProps<RecordType> {
childrenColumnName: string;
}

function Body<RecordType>({
data,
getRowKey,
measureColumnWidth,
expandedKeys,
onRow,
rowExpandable,
emptyNode,
childrenColumnName,
}: BodyProps<RecordType>) {
function Body<RecordType>(props: BodyProps<RecordType>) {
if (process.env.NODE_ENV !== 'production') {
devRenderTimes(props);
}

const {
data,
getRowKey,
measureColumnWidth,
expandedKeys,
onRow,
rowExpandable,
emptyNode,
childrenColumnName,
} = props;

const { prefixCls, getComponent, onColumnResize, flattenColumns } = useContext(TableContext, [
'prefixCls',
'getComponent',
Expand All @@ -47,58 +54,57 @@ function Body<RecordType>({
});

// ====================== Render ======================
const bodyNode = React.useMemo(() => {
const WrapperComponent = getComponent(['body', 'wrapper'], 'tbody');
const trComponent = getComponent(['body', 'row'], 'tr');
const tdComponent = getComponent(['body', 'cell'], 'td');
const thComponent = getComponent(['body', 'cell'], 'th');
const WrapperComponent = getComponent(['body', 'wrapper'], 'tbody');
const trComponent = getComponent(['body', 'row'], 'tr');
const tdComponent = getComponent(['body', 'cell'], 'td');
const thComponent = getComponent(['body', 'cell'], 'th');

let rows: React.ReactNode;
if (data.length) {
rows = flattenData.map((item, idx) => {
const { record, indent, index: renderIndex } = item;
let rows: React.ReactNode;
if (data.length) {
rows = flattenData.map((item, idx) => {
const { record, indent, index: renderIndex } = item;

const key = getRowKey(record, idx);
const key = getRowKey(record, idx);

return (
<BodyRow
key={key}
rowKey={key}
record={record}
recordKey={key}
index={idx}
renderIndex={renderIndex}
rowComponent={trComponent}
cellComponent={tdComponent}
scopeCellComponent={thComponent}
expandedKeys={expandedKeys}
onRow={onRow}
getRowKey={getRowKey}
rowExpandable={rowExpandable}
childrenColumnName={childrenColumnName}
indent={indent}
/>
);
});
} else {
rows = (
<ExpandedRow
expanded
className={`${prefixCls}-placeholder`}
prefixCls={prefixCls}
component={trComponent}
return (
<BodyRow
key={key}
rowKey={key}
record={record}
index={idx}
renderIndex={renderIndex}
rowComponent={trComponent}
cellComponent={tdComponent}
colSpan={flattenColumns.length}
isEmpty
>
{emptyNode}
</ExpandedRow>
scopeCellComponent={thComponent}
expandedKeys={expandedKeys}
onRow={onRow}
getRowKey={getRowKey}
rowExpandable={rowExpandable}
childrenColumnName={childrenColumnName}
indent={indent}
/>
);
}
});
} else {
rows = (
<ExpandedRow
expanded
className={`${prefixCls}-placeholder`}
prefixCls={prefixCls}
component={trComponent}
cellComponent={tdComponent}
colSpan={flattenColumns.length}
isEmpty
>
{emptyNode}
</ExpandedRow>
);
}

const columnsKey = getColumnsKey(flattenColumns);
const columnsKey = getColumnsKey(flattenColumns);

return (
return (
<PerfContext.Provider value={perfRef.current}>
<WrapperComponent className={`${prefixCls}-tbody`}>
{/* Measure body column width with additional hidden col */}
{measureColumnWidth && (
Expand All @@ -111,27 +117,10 @@ function Body<RecordType>({

{rows}
</WrapperComponent>
);
}, [
data,
prefixCls,
onRow,
measureColumnWidth,
expandedKeys,
getRowKey,
getComponent,
emptyNode,
flattenColumns,
childrenColumnName,
onColumnResize,
rowExpandable,
flattenData,
]);

return <PerfContext.Provider value={perfRef.current}>{bodyNode}</PerfContext.Provider>;
</PerfContext.Provider>
);
}

const MemoBody = React.memo(Body);
MemoBody.displayName = 'Body';
Body.displayName = 'Body';

export default MemoBody;
export default responseImmutable(Body);
4 changes: 2 additions & 2 deletions src/FixedHolder/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import ColGroup from '../ColGroup';
import TableContext from '../context/TableContext';
import type { HeaderProps } from '../Header/Header';
import devRenderTimes from '../hooks/useRenderTimes';
import type { ColumnsType, ColumnType } from '../interface';
import type { ColumnsType, ColumnType, Direction } from '../interface';

function useColumnWidth(colWidths: readonly number[], columCount: number) {
return useMemo(() => {
Expand All @@ -30,7 +30,7 @@ export interface FixedHeaderProps<RecordType> extends HeaderProps<RecordType> {
maxContentScroll: boolean;
colWidths: readonly number[];
columCount: number;
direction: 'ltr' | 'rtl';
direction: Direction;
fixHeader: boolean;
stickyTopOffset?: number;
stickyBottomOffset?: number;
Expand Down
Loading

1 comment on commit ecf3fdb

@vercel
Copy link

@vercel vercel bot commented on ecf3fdb Dec 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

table – ./

table-git-master-react-component.vercel.app
table-react-component.vercel.app

Please sign in to comment.