Skip to content

Commit

Permalink
feat: deepcompare column prop to avoid endless loop
Browse files Browse the repository at this point in the history
  • Loading branch information
hemengke1997 committed Dec 6, 2021
1 parent 0344088 commit 21ee389
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 63 deletions.
5 changes: 4 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ module.exports = {
"react/jsx-no-undef": 2,
"react/jsx-wrap-multilines": 2,
"react/no-string-refs": 0,
"no-plusplus": 0
"no-plusplus": 0,
"react-hooks/exhaustive-deps": 0,
"consistent-return": 0,
"@typescript-eslint/consistent-type-imports": 0
},
};
35 changes: 2 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,6 @@
yarn add use-antd-resizable-header
```

## 最佳实践

为了规避循环渲染问题,建议:

- columns 为常量时,提到组件外,或使用 `React.useMemo`, `React.useRef` 包裹常量
- 更建议, 封装 table 组件,把 columns 作为 prop 传入

```tsx
function ResizableTable<DataType extends Record<string, any>>(props: TableProps<DataType>) {
const { columns: columnsProp, scroll, ...rest } = props;

const { resizableColumns, components, tableWidth } = useATRH({
columns: columnsProp,
minConstraints: 50,
});

return (
<Table
columns={columns}
scroll={{ ...scroll, x: tableWidth }}
components={components}
{...rest}
></Table>
);
}
```

## 注意事项

- **默认拖动颜色为`#000`,可通过`global`或设置 css 变量`--atrh-color`设置颜色**
Expand All @@ -53,9 +26,9 @@ function ResizableTable<DataType extends Record<string, any>>(props: TableProps<
import useATRH from 'use-antd-resizable-header';
import 'use-antd-resizable-header/dist/style.css';

const columns = [];

function App() {
const columns = [];

const { components, resizableColumns, tableWidth } = useATRH({ columns });

return (
Expand Down Expand Up @@ -299,10 +272,6 @@ function App() {
export default App;
```

## TODO

- [ ] 测试用例

## MIT

[LICENSE](https://github.com/hemengke1997/useATRH/blob/master/LICENSE)
Binary file modified image/preview.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "use-antd-resizable-header",
"version": "1.4.5",
"version": "1.4.6",
"description": "antd resizable header column hook",
"author": "hemengke1997 <23536175@qq.com>",
"types": "dist/index.d.ts",
Expand Down Expand Up @@ -36,12 +36,16 @@
"classnames": "^2.3.1",
"lodash.debounce": "^4.0.8",
"lodash.isempty": "4.4.0",
"lodash.isequalwith": "^4.4.0",
"lodash.isfunction": "^3.0.9",
"lodash.throttle": "^4.1.1",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-resizable": "^3.0.4"
},
"devDependencies": {
"@types/lodash.isequalwith": "^4.4.6",
"@types/lodash.isfunction": "^3.0.6",
"@types/node": "^16.0.0",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
Expand Down
32 changes: 32 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/ResizableHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ const ResizableHeader: React.FC<ComponentProp> = (props) => {
>
<div style={{ width: resizeWidth, height: '100%' }}></div>
</Resizable>
<div {...rest} className="resizable-title" title={title}>
{children}
<div {...rest} className="resizable-title">
<span title={title}>{children}</span>
</div>
</th>
);
Expand Down
5 changes: 2 additions & 3 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,14 @@

&:active,
&:hover {
z-index: 5;
cursor: col-resize;

& .resizable-line {
background: var(--atrh-color, #000);
pointer-events: none;
}
}
&:active {
z-index: 5;
}
}

& .resizable-fake-box {
Expand Down
46 changes: 23 additions & 23 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import isEmpty from 'lodash.isempty';
import useThrottleEffect from './utils/useThrottleEffect';
import useDebounceFn from './utils/useDebounceFn';
import { depthFirstSearch, getUniqueId } from './utils';
import useDeepFnCompareEffect from './utils/useDeepFnCompare';

type useTableResizableHeaderProps<ColumnType> = {
columns: ColumnType[] | undefined;
Expand Down Expand Up @@ -75,34 +76,33 @@ function useTableResizableHeader<ColumnType extends Record<string, any>>(

const getColumns = React.useCallback(
(list: ColumnType[]) => {
const c = list
?.filter((item) => !isEmpty(item))
.map((col, index) => {
return {
...col,
children: col?.children?.length ? getColumns(col.children) : undefined,
onHeaderCell: (column: ColumnType) => {
return {
title: typeof col?.title === 'string' ? col?.title : '',
width: widthCache.current?.get(column[getKey])?.width || column?.width,
onMount: onMount(column?.[getKey]),
onResize: onResize(column?.[getKey]),
minWidth: minConstraints,
maxWidth: maxConstraints,
triggerRender,
};
},
width: widthCache.current?.get(col[getKey])?.width || col?.width,
ellipsis: typeof col.ellipsis !== 'undefined' ? col.ellipsis : true,
[getKey]: col[getKey] || col['key'] || getUniqueId(index),
};
}) as ColumnType[];
const trulyColumns = list?.filter((item) => !isEmpty(item));
const c = trulyColumns.map((col, index) => {
return {
...col,
children: col?.children?.length ? getColumns(col.children) : undefined,
onHeaderCell: (column: ColumnType) => {
return {
title: typeof col?.title === 'string' ? col?.title : '',
width: widthCache.current?.get(column[getKey])?.width || column?.width,
onMount: onMount(column?.[getKey]),
onResize: onResize(column?.[getKey]),
minWidth: minConstraints,
maxWidth: maxConstraints,
triggerRender,
};
},
width: widthCache.current?.get(col[getKey])?.width || col?.width,
ellipsis: typeof col.ellipsis !== 'undefined' ? col.ellipsis : true,
[getKey]: col[getKey] || col.key || getUniqueId(index),
};
}) as ColumnType[];
return c;
},
[onMount, onResize, widthCache.current],
);

useEffect(() => {
useDeepFnCompareEffect(() => {
if (columns) {
const c = getColumns(columns);
setResizableColumns(c);
Expand Down
26 changes: 26 additions & 0 deletions src/utils/useDeepFnCompare.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import isEqualWith from 'lodash.isequalwith';
import isFunction from 'lodash.isfunction';
import { useEffect, useRef } from 'react';
import type { DependencyList, EffectCallback } from 'react';

const depsEqual = (aDeps: DependencyList, bDeps: DependencyList = []) => {
return isEqualWith(aDeps, bDeps, (a, b) => {
if (isFunction(a) && isFunction(b) && a.toString() === b.toString()) {
return true;
}
});
};

const useDeepFnCompareEffect = (effect: EffectCallback, deps: DependencyList) => {
const ref = useRef<DependencyList>();
const signalRef = useRef<number>(0);

if (!depsEqual(deps, ref.current)) {
ref.current = deps;
signalRef.current += 1;
}

useEffect(effect, [signalRef.current]);
};

export default useDeepFnCompareEffect;

0 comments on commit 21ee389

Please sign in to comment.