From 153e88a3be08f0719b5010cf7e71474d65ca555b Mon Sep 17 00:00:00 2001 From: lijinke666 Date: Mon, 11 Nov 2024 18:08:35 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20=E5=87=8F=E5=B0=91=E5=BC=80=E5=90=AF?= =?UTF-8?q?=20ReactDOM.unstable=5FbatchedUpdates=20=E5=90=8E=E7=9A=84?= =?UTF-8?q?=E9=87=8D=E6=B8=B2=E6=9F=93=E6=AC=A1=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unit/sheet-type/pivot-sheet-spec.ts | 10 ++++----- .../s2-core/src/common/interface/s2Options.ts | 2 +- .../s2-core/src/sheet-type/spread-sheet.ts | 6 +++--- packages/s2-core/src/utils/hide-columns.ts | 2 +- packages/s2-react/src/hooks/useSpreadSheet.ts | 21 ++++++++++++++----- .../docs/api/basic-class/spreadsheet.zh.md | 2 +- .../docs/api/components/sheet-component.zh.md | 2 +- s2-site/docs/manual/migration-v2.zh.md | 13 +++++++----- 8 files changed, 36 insertions(+), 22 deletions(-) diff --git a/packages/s2-core/__tests__/unit/sheet-type/pivot-sheet-spec.ts b/packages/s2-core/__tests__/unit/sheet-type/pivot-sheet-spec.ts index 743030fc75..80cfd60646 100644 --- a/packages/s2-core/__tests__/unit/sheet-type/pivot-sheet-spec.ts +++ b/packages/s2-core/__tests__/unit/sheet-type/pivot-sheet-spec.ts @@ -773,7 +773,7 @@ describe('PivotSheet Tests', () => { test('should rebuild hidden columns detail by status', async () => { // 重新更新, 但是没有隐藏列信息 - await s2.render({ reloadData: false, reBuildHiddenColumnsDetail: true }); + await s2.render({ reloadData: false, rebuildHiddenColumnsDetail: true }); expect(mockHideColumnsByThunkGroup).toHaveBeenCalledTimes(0); @@ -781,16 +781,16 @@ describe('PivotSheet Tests', () => { null, ] as unknown as HiddenColumnsInfo[]); - // 重新更新, 有隐藏列信息, 但是 reBuildHiddenColumnsDetail 为 false + // 重新更新, 有隐藏列信息, 但是 rebuildHiddenColumnsDetail 为 false await s2.render({ reloadData: false, - reBuildHiddenColumnsDetail: false, + rebuildHiddenColumnsDetail: false, }); expect(mockHideColumnsByThunkGroup).toHaveBeenCalledTimes(0); - // 重新更新, 有隐藏列信息, 且 reBuildHiddenColumnsDetail 为 true - await s2.render({ reloadData: false, reBuildHiddenColumnsDetail: true }); + // 重新更新, 有隐藏列信息, 且 rebuildHiddenColumnsDetail 为 true + await s2.render({ reloadData: false, rebuildHiddenColumnsDetail: true }); expect(mockHideColumnsByThunkGroup).toHaveBeenCalledTimes(1); }); diff --git a/packages/s2-core/src/common/interface/s2Options.ts b/packages/s2-core/src/common/interface/s2Options.ts index d8ece16a92..8639a59e2e 100644 --- a/packages/s2-core/src/common/interface/s2Options.ts +++ b/packages/s2-core/src/common/interface/s2Options.ts @@ -386,5 +386,5 @@ export interface S2RenderOptions { /** * 是否重新生成列头隐藏信息 */ - reBuildHiddenColumnsDetail?: boolean; + rebuildHiddenColumnsDetail?: boolean; } diff --git a/packages/s2-core/src/sheet-type/spread-sheet.ts b/packages/s2-core/src/sheet-type/spread-sheet.ts index b1991c8938..e5d5710f6e 100644 --- a/packages/s2-core/src/sheet-type/spread-sheet.ts +++ b/packages/s2-core/src/sheet-type/spread-sheet.ts @@ -423,7 +423,7 @@ export abstract class SpreadSheet extends EE { const { reloadData = true, rebuildDataSet = false, - reBuildHiddenColumnsDetail = true, + rebuildHiddenColumnsDetail = true, } = options || {}; this.emit(S2Event.LAYOUT_BEFORE_RENDER); @@ -439,7 +439,7 @@ export abstract class SpreadSheet extends EE { this.buildFacet(); - if (reBuildHiddenColumnsDetail) { + if (rebuildHiddenColumnsDetail) { await this.initHiddenColumnsDetail(); } @@ -456,7 +456,7 @@ export abstract class SpreadSheet extends EE { s2.render({ reloadData: true; rebuildDataSet: true; - reBuildHiddenColumnsDetail: true; + rebuildHiddenColumnsDetail: true; }) */ public async render(options?: S2RenderOptions | boolean): Promise { diff --git a/packages/s2-core/src/utils/hide-columns.ts b/packages/s2-core/src/utils/hide-columns.ts index 2c71b16ea7..9c59de0128 100644 --- a/packages/s2-core/src/utils/hide-columns.ts +++ b/packages/s2-core/src/utils/hide-columns.ts @@ -131,7 +131,7 @@ export const hideColumns = async ( spreadsheet.store.set('hiddenColumnsDetail', hiddenColumnsDetail); await spreadsheet.render({ reloadData: false, - reBuildHiddenColumnsDetail: false, + rebuildHiddenColumnsDetail: false, }); }; diff --git a/packages/s2-react/src/hooks/useSpreadSheet.ts b/packages/s2-react/src/hooks/useSpreadSheet.ts index 2b37860b41..1368be315f 100644 --- a/packages/s2-react/src/hooks/useSpreadSheet.ts +++ b/packages/s2-react/src/hooks/useSpreadSheet.ts @@ -1,7 +1,8 @@ +/* eslint-disable max-lines-per-function */ import type { S2DataConfig, S2Options, ThemeCfg } from '@antv/s2'; import { PivotSheet, SpreadSheet, TableSheet } from '@antv/s2'; import { useUpdate, useUpdateEffect } from 'ahooks'; -import { identity } from 'lodash'; +import { identity, isEqual } from 'lodash'; import React from 'react'; import type { SheetComponentOptions, SheetComponentProps } from '../components'; import { getSheetComponentOptions } from '../utils'; @@ -106,10 +107,11 @@ export function useSpreadSheet(props: SheetComponentProps) { updatePrevDepsRef.current = [dataCfg, options!, themeCfg!]; + let rerender = false; let reloadData = false; let rebuildDataSet = false; - if (!Object.is(prevDataCfg, dataCfg)) { + if (!isEqual(prevDataCfg, dataCfg)) { // 列头变化需要重新计算初始叶子节点 if ( prevDataCfg?.fields?.columns?.length !== @@ -119,13 +121,15 @@ export function useSpreadSheet(props: SheetComponentProps) { } reloadData = true; + rerender = true; s2Ref.current?.setDataCfg(dataCfg); } - if (!Object.is(prevOptions, options)) { - if (!Object.is(prevOptions?.hierarchyType, options?.hierarchyType)) { + if (!isEqual(prevOptions, options)) { + if (!isEqual(prevOptions?.hierarchyType, options?.hierarchyType)) { rebuildDataSet = true; reloadData = true; + rerender = true; s2Ref.current?.setDataCfg(dataCfg); } @@ -133,10 +137,17 @@ export function useSpreadSheet(props: SheetComponentProps) { s2Ref.current?.changeSheetSize(options!.width, options!.height); } - if (!Object.is(prevThemeCfg, themeCfg)) { + if (!isEqual(prevThemeCfg, themeCfg)) { + rerender = true; s2Ref.current?.setThemeCfg(themeCfg); } + if (!rerender) { + setLoading(false); + + return; + } + /** * onUpdate 交出控制权 * 由传入方决定最终的 render 模式 diff --git a/s2-site/docs/api/basic-class/spreadsheet.zh.md b/s2-site/docs/api/basic-class/spreadsheet.zh.md index 66141907d3..561db92461 100644 --- a/s2-site/docs/api/basic-class/spreadsheet.zh.md +++ b/s2-site/docs/api/basic-class/spreadsheet.zh.md @@ -47,7 +47,7 @@ s2.isPivotMode() | setOptions | 更新表格配置 | (options: [S2Options](/docs/api/general/S2Options), reset?: boolean) => void | `reset` 参数需在 `@antv/s2^1.34.0`版本使用 | | resetDataCfg | 重置表格数据 | () => void | | | resetOptions | 重置表格配置 | () => void | | -| render | 重新渲染表格,如果 `reloadData` = true, 则会重新计算数据,`rebuildDataSet` = true, 重新构建数据集,`reBuildHiddenColumnsDetail` = true 重新构建隐藏列信息 | `(reloadData?: boolean \| { reloadData?: boolean, rebuildDataSet?: boolean; reBuildHiddenColumnsDetail?: boolean }) => Promise` | | +| render | 重新渲染表格,如果 `reloadData` = true, 则会重新计算数据,`rebuildDataSet` = true, 重新构建数据集,`rebuildHiddenColumnsDetail` = true 重新构建隐藏列信息 | `(reloadData?: boolean \| { reloadData?: boolean, rebuildDataSet?: boolean; rebuildHiddenColumnsDetail?: boolean }) => Promise` | | | destroy | 销毁表格 | `() => void` | | | setThemeCfg | 更新主题配置 (含主题 schema, 色板,主题名) | (themeCfg: [ThemeCfg](/docs/api/general/S2Theme/#themecfg)) => void | | | setTheme | 更新主题 (只包含主题 scheme) | (theme: [S2Theme](/docs/api/general/S2Theme/#s2theme)) => void | | diff --git a/s2-site/docs/api/components/sheet-component.zh.md b/s2-site/docs/api/components/sheet-component.zh.md index 5a236bd93a..81df202dfe 100644 --- a/s2-site/docs/api/components/sheet-component.zh.md +++ b/s2-site/docs/api/components/sheet-component.zh.md @@ -354,7 +354,7 @@ type SheetComponentOptions = S2Options< | -- | -- | -- | -- | --- | | reloadData | 是否重新加载数据 | `boolean` | | | | rebuildDataSet | 是否重新生成数据集 | `boolean` | | | -| reBuildHiddenColumnsDetail | 是否重新生成列头隐藏信息 | `boolean` | | | +| rebuildHiddenColumnsDetail | 是否重新生成列头隐藏信息 | `boolean` | | | diff --git a/s2-site/docs/manual/migration-v2.zh.md b/s2-site/docs/manual/migration-v2.zh.md index 398ad7f7d2..974e03cac2 100644 --- a/s2-site/docs/manual/migration-v2.zh.md +++ b/s2-site/docs/manual/migration-v2.zh.md @@ -621,17 +621,20 @@ render 函数的参数从 `boolean` 扩展为 `boolean | object`, 当为 `boolea + s2.render({ reloadData: false }) // 等价于 s2.render(false) + s2.render({ + reloadData: false, -+ reBuildHiddenColumnsDetail: false, ++ rebuildHiddenColumnsDetail: false, + }); ``` `reBuildDataSet` 重命名为 `rebuildDataSet`: +`reBuildHiddenColumnsDetail` 重命名为 `rebuildHiddenColumnsDetail`: ```diff -+ s2.render({ -- reBuildDataSet: false, -+ rebuildDataSet: false, -+ }); +s2.render({ +- reBuildDataSet: false, ++ rebuildDataSet: false, +- reBuildHiddenColumnsDetail: false, ++ rebuildHiddenColumnsDetail: false, +}); ``` #### 小计总计配置参数变更 From 4af50b566393293271a5e55b5765fa3ea32af40b Mon Sep 17 00:00:00 2001 From: lijinke666 Date: Tue, 12 Nov 2024 11:21:28 +0800 Subject: [PATCH 2/3] =?UTF-8?q?test:=20=E8=A1=A5=E5=85=85=E5=8D=95?= =?UTF-8?q?=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unit/hooks/useSpreadSheet-spec.ts | 98 ++++++++++++------- packages/s2-react/src/hooks/useSpreadSheet.ts | 2 +- 2 files changed, 61 insertions(+), 39 deletions(-) diff --git a/packages/s2-react/__tests__/unit/hooks/useSpreadSheet-spec.ts b/packages/s2-react/__tests__/unit/hooks/useSpreadSheet-spec.ts index ba5d76e0ec..6ca3355795 100644 --- a/packages/s2-react/__tests__/unit/hooks/useSpreadSheet-spec.ts +++ b/packages/s2-react/__tests__/unit/hooks/useSpreadSheet-spec.ts @@ -23,6 +23,7 @@ describe('useSpreadSheet tests', () => { fields: S2DataConfig['fields'] = mockDataConfig.fields, ): SheetComponentProps => { return { + sheetType: 'pivot' as const, spreadsheet: () => new PivotSheet(getContainer(), mockDataConfig, s2Options as S2Options), options: s2Options, @@ -35,9 +36,7 @@ describe('useSpreadSheet tests', () => { test('should build spreadSheet', async () => { const props = getConfig(); - const { result } = renderHook(() => - useSpreadSheet({ ...props, sheetType: 'pivot' }), - ); + const { result } = renderHook(() => useSpreadSheet({ ...props })); await waitFor(() => { expect(result.current.s2Ref).toBeDefined(); @@ -47,7 +46,6 @@ describe('useSpreadSheet tests', () => { test('should cannot change table size when width or height updated and disable adaptive', async () => { const props = { ...getConfig(), - sheetType: 'pivot' as const, adaptive: false, }; const { result } = renderHook(() => useSpreadSheet(props)); @@ -126,7 +124,6 @@ describe('useSpreadSheet tests', () => { const props = { ...getConfig(), - sheetType: 'pivot' as const, onDestroy: onDestroyFromProps, }; const { result, unmount } = renderHook(() => useSpreadSheet(props)); @@ -160,7 +157,6 @@ describe('useSpreadSheet tests', () => { const props = { ...getConfig(), - sheetType: 'pivot' as const, onMounted, }; const { result } = renderHook(() => useSpreadSheet(props)); @@ -173,40 +169,67 @@ describe('useSpreadSheet tests', () => { }); }); - test('should call onUpdate and onUpdateAfterRender when sheet updated', async () => { - const onUpdate = jest.fn(); - const onUpdateAfterRender = jest.fn(); - - const props = { - ...getConfig(), - sheetType: 'pivot' as const, - onUpdate, - onUpdateAfterRender, - }; - const { rerender } = renderHook( - (innerProps) => useSpreadSheet(innerProps), - { - initialProps: props, + test.each([ + { + updatedProps: { + options: { width: 200 }, }, - ); - - await waitFor(() => { - expect(onUpdate).toHaveBeenCalledTimes(0); - expect(onUpdateAfterRender).toHaveBeenCalledTimes(0); - }); - - act(() => { - rerender({ ...props, options: { width: 200 } }); - }); - - await waitFor(() => { - expect(onUpdate).toHaveBeenCalledWith({ + updateOptions: { rebuildDataSet: false, reloadData: false, + }, + }, + { + updatedProps: { + themeCfg: { name: 'dark' }, + }, + updateOptions: { + rebuildDataSet: false, + reloadData: false, + }, + }, + { + updatedProps: { + dataCfg: { fields: ['test'] }, + }, + updateOptions: { + rebuildDataSet: false, + reloadData: true, + }, + }, + ])( + 'should call onUpdate and onUpdateAfterRender when sheet %o updated', + async ({ updatedProps, updateOptions }) => { + const onUpdate = jest.fn(); + const onUpdateAfterRender = jest.fn(); + + const props = { + ...getConfig(), + onUpdate, + onUpdateAfterRender, + }; + const { rerender } = renderHook( + (innerProps) => useSpreadSheet(innerProps), + { + initialProps: props, + }, + ); + + await waitFor(() => { + expect(onUpdate).toHaveBeenCalledTimes(0); + expect(onUpdateAfterRender).toHaveBeenCalledTimes(0); }); - expect(onUpdateAfterRender).toHaveBeenCalledTimes(1); - }); - }); + + act(() => { + rerender({ ...props, ...updatedProps }); + }); + + await waitFor(() => { + expect(onUpdate).toHaveBeenCalledWith(updateOptions); + expect(onUpdateAfterRender).toHaveBeenCalledTimes(1); + }); + }, + ); test('should use custom render mode by onUpdate', async () => { const onUpdate = jest.fn((options) => ({ ...options, reloadData: true })); @@ -214,7 +237,6 @@ describe('useSpreadSheet tests', () => { const props = { ...getConfig(), - sheetType: 'pivot' as const, onUpdate, onUpdateAfterRender, }; @@ -226,7 +248,7 @@ describe('useSpreadSheet tests', () => { ); act(() => { - rerender({ ...props, options: { width: 200 } }); + rerender({ ...props, options: { width: 300 } }); }); await waitFor(() => { diff --git a/packages/s2-react/src/hooks/useSpreadSheet.ts b/packages/s2-react/src/hooks/useSpreadSheet.ts index 1368be315f..72da52a607 100644 --- a/packages/s2-react/src/hooks/useSpreadSheet.ts +++ b/packages/s2-react/src/hooks/useSpreadSheet.ts @@ -129,10 +129,10 @@ export function useSpreadSheet(props: SheetComponentProps) { if (!isEqual(prevOptions?.hierarchyType, options?.hierarchyType)) { rebuildDataSet = true; reloadData = true; - rerender = true; s2Ref.current?.setDataCfg(dataCfg); } + rerender = true; s2Ref.current?.setOptions(options as S2Options); s2Ref.current?.changeSheetSize(options!.width, options!.height); } From 2d7460254dad282fc3dff015f94c5b2ff477ca54 Mon Sep 17 00:00:00 2001 From: lijinke666 Date: Thu, 14 Nov 2024 11:29:54 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=E6=AF=94=E8=BE=83=20dataCfg=20?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=20Object.is?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/s2-react/src/hooks/useSpreadSheet.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/s2-react/src/hooks/useSpreadSheet.ts b/packages/s2-react/src/hooks/useSpreadSheet.ts index 72da52a607..7426b975fa 100644 --- a/packages/s2-react/src/hooks/useSpreadSheet.ts +++ b/packages/s2-react/src/hooks/useSpreadSheet.ts @@ -111,7 +111,7 @@ export function useSpreadSheet(props: SheetComponentProps) { let reloadData = false; let rebuildDataSet = false; - if (!isEqual(prevDataCfg, dataCfg)) { + if (!Object.is(prevDataCfg, dataCfg)) { // 列头变化需要重新计算初始叶子节点 if ( prevDataCfg?.fields?.columns?.length !== @@ -126,7 +126,7 @@ export function useSpreadSheet(props: SheetComponentProps) { } if (!isEqual(prevOptions, options)) { - if (!isEqual(prevOptions?.hierarchyType, options?.hierarchyType)) { + if (prevOptions?.hierarchyType !== options?.hierarchyType) { rebuildDataSet = true; reloadData = true; s2Ref.current?.setDataCfg(dataCfg);