@hsu-react/ui 2.5.3 → 2.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/es/components/ChainGraph/_hooks/useChainGraphData.js +29 -8
  2. package/es/components/ChainGraph/_hooks/useChainGraphLayout.js +14 -3
  3. package/es/components/Chart/Bar/index.js +49 -19
  4. package/es/components/Chart/Bubble/index.js +21 -6
  5. package/es/components/Chart/Common/index.js +7 -2
  6. package/es/components/Chart/Heatmap/index.js +21 -6
  7. package/es/components/Chart/Line/index.js +49 -19
  8. package/es/components/Chart/Pie/Pie3D/index.js +22 -6
  9. package/es/components/Chart/Pie/index.js +21 -6
  10. package/es/components/Chart/Sankey/index.js +11 -2
  11. package/es/components/Chart/Tree/index.js +11 -2
  12. package/es/components/Chat/ChatInput/index.js +7 -2
  13. package/es/components/Icon/index.js +8 -2
  14. package/es/components/Input/Number/index.js +28 -21
  15. package/es/components/Input/Password/index.js +44 -36
  16. package/es/components/Input/Search/index.js +44 -36
  17. package/es/components/Input/TextArea/index.js +64 -42
  18. package/es/components/Input/index.js +40 -34
  19. package/es/components/Select/_hooks/useSelectComposition.js +6 -2
  20. package/es/components/Select/_hooks/useSelectInputOptions.js +8 -2
  21. package/es/components/Slider/index.js +24 -15
  22. package/es/components/Table/_hooks/useAutoScrolling.js +16 -7
  23. package/es/components/Upload/_hooks/useUploadFileList.js +8 -2
  24. package/es/components/Upload/_hooks/useUploadOperations.js +8 -2
  25. package/es/hooks/useLatestRef.d.ts +24 -0
  26. package/es/hooks/useLatestRef.js +29 -0
  27. package/es/layout/Menu/_hooks/useOnlyLvOneMenu.js +9 -2
  28. package/lib/components/ChainGraph/_hooks/useChainGraphData.js +24 -7
  29. package/lib/components/ChainGraph/_hooks/useChainGraphLayout.js +12 -2
  30. package/lib/components/Chart/Bar/index.js +45 -18
  31. package/lib/components/Chart/Bubble/index.js +19 -6
  32. package/lib/components/Chart/Common/index.js +6 -2
  33. package/lib/components/Chart/Heatmap/index.js +19 -6
  34. package/lib/components/Chart/Line/index.js +45 -18
  35. package/lib/components/Chart/Pie/Pie3D/index.js +20 -6
  36. package/lib/components/Chart/Pie/index.js +19 -6
  37. package/lib/components/Chart/Sankey/index.js +10 -2
  38. package/lib/components/Chart/Tree/index.js +10 -2
  39. package/lib/components/Chat/ChatInput/index.js +6 -2
  40. package/lib/components/Icon/index.js +7 -2
  41. package/lib/components/Input/Number/index.js +27 -18
  42. package/lib/components/Input/Password/index.js +40 -26
  43. package/lib/components/Input/Search/index.js +42 -26
  44. package/lib/components/Input/TextArea/index.js +54 -26
  45. package/lib/components/Input/index.js +37 -24
  46. package/lib/components/Select/_hooks/useSelectComposition.js +6 -2
  47. package/lib/components/Select/_hooks/useSelectInputOptions.js +7 -2
  48. package/lib/components/Slider/index.js +23 -11
  49. package/lib/components/Table/_hooks/useAutoScrolling.js +16 -7
  50. package/lib/components/Upload/_hooks/useUploadFileList.js +7 -2
  51. package/lib/components/Upload/_hooks/useUploadOperations.js +7 -2
  52. package/lib/hooks/useLatestRef.d.ts +24 -0
  53. package/lib/hooks/useLatestRef.js +35 -0
  54. package/lib/layout/Menu/_hooks/useOnlyLvOneMenu.js +8 -2
  55. package/package.json +9 -3
  56. package/src/__tests__/callbackDepsGuard.test.ts +119 -0
  57. package/src/__tests__/setup.ts +26 -0
  58. package/src/components/ChainGraph/_hooks/callbacks.test.tsx +155 -0
  59. package/src/components/ChainGraph/_hooks/useChainGraphData.ts +38 -10
  60. package/src/components/ChainGraph/_hooks/useChainGraphLayout.ts +16 -3
  61. package/src/components/Chart/Bar/index.tsx +59 -21
  62. package/src/components/Chart/Bubble/index.tsx +22 -7
  63. package/src/components/Chart/Common/index.tsx +7 -2
  64. package/src/components/Chart/Heatmap/index.tsx +25 -6
  65. package/src/components/Chart/Line/index.tsx +59 -21
  66. package/src/components/Chart/Pie/Pie3D/index.tsx +22 -7
  67. package/src/components/Chart/Pie/index.tsx +22 -7
  68. package/src/components/Chart/Sankey/index.tsx +10 -4
  69. package/src/components/Chart/Tree/index.tsx +10 -4
  70. package/src/components/Chart/callbacks.test.tsx +315 -0
  71. package/src/components/Chat/ChatInput/index.tsx +7 -2
  72. package/src/components/Icon/index.tsx +7 -2
  73. package/src/components/Input/Number/index.tsx +25 -23
  74. package/src/components/Input/Password/index.tsx +37 -26
  75. package/src/components/Input/Search/index.tsx +39 -26
  76. package/src/components/Input/TextArea/index.test.tsx +208 -0
  77. package/src/components/Input/TextArea/index.tsx +56 -30
  78. package/src/components/Input/index.test.tsx +189 -0
  79. package/src/components/Input/index.tsx +36 -29
  80. package/src/components/Select/_hooks/useSelectComposition.test.ts +47 -0
  81. package/src/components/Select/_hooks/useSelectComposition.ts +6 -2
  82. package/src/components/Select/_hooks/useSelectInputOptions.ts +6 -9
  83. package/src/components/Slider/index.tsx +22 -12
  84. package/src/components/Table/_hooks/useAutoScrolling.test.tsx +95 -0
  85. package/src/components/Table/_hooks/useAutoScrolling.ts +16 -7
  86. package/src/components/Upload/_hooks/useUploadFileList.ts +6 -2
  87. package/src/components/Upload/_hooks/useUploadOperations.ts +7 -2
  88. package/src/hooks/useLatestRef.ts +31 -0
  89. package/src/layout/Menu/_hooks/useOnlyLvOneMenu.test.tsx +56 -0
  90. package/src/layout/Menu/_hooks/useOnlyLvOneMenu.ts +8 -2
@@ -4,8 +4,9 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
4
4
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
5
5
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
6
6
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
- import { useEffect, useState } from "react";
7
+ import { useCallback, useEffect, useState } from "react";
8
8
  import { Equal } from "hsu-utils";
9
+ import { useLatestRef } from "../../../hooks/useLatestRef";
9
10
  export function useChainGraphData(props) {
10
11
  var graph = props.graph,
11
12
  data = props.data,
@@ -22,6 +23,29 @@ export function useChainGraphData(props) {
22
23
  _useState4 = _slicedToArray(_useState3, 2),
23
24
  isLayouting = _useState4[0],
24
25
  setIsLayouting = _useState4[1];
26
+
27
+ // 这三个回调都是「交给图实例、由它在后续事件里回调」的出口,不是数据本身。
28
+ // 它们进依赖数组是条死依赖:effect 体被 ObjEqual(lastData, data) 挡住,
29
+ // 引用变了也不会重新 setData —— 图里存的还是首次 setData 时那个闭包,
30
+ // 换了引用永远调不到(stale closure)。改成引用恒定的转发函数:
31
+ // 依赖数组只留真正的输入(graph/data/level/rootLevel),调用时总是取到最新的回调。
32
+ var getImageRef = useLatestRef(getImage);
33
+ var labelRenderRef = useLatestRef(labelRender);
34
+ var onLayoutingChangeRef = useLatestRef(onLayoutingChange);
35
+ var emitImage = useCallback(function (img) {
36
+ var _getImageRef$current;
37
+ (_getImageRef$current = getImageRef.current) === null || _getImageRef$current === void 0 || _getImageRef$current.call(getImageRef, img);
38
+ }, [getImageRef]);
39
+ // labelRender 在 ChainGraphServices.setData 里是「传了才改写 label」的真值判断,
40
+ // 所以这里保留「有没有传」的语义:没传就传 undefined,传了才给转发函数。
41
+ var renderLabel = useCallback(function (label) {
42
+ return labelRenderRef.current(label);
43
+ }, [labelRenderRef]);
44
+ var emitLayouting = useCallback(function (value) {
45
+ var _onLayoutingChangeRef;
46
+ setIsLayouting(value);
47
+ (_onLayoutingChangeRef = onLayoutingChangeRef.current) === null || _onLayoutingChangeRef === void 0 || _onLayoutingChangeRef.call(onLayoutingChangeRef, value);
48
+ }, [onLayoutingChangeRef]);
25
49
  useEffect(function () {
26
50
  if (graph && !Equal.ObjEqual(lastData, data)) {
27
51
  setLastData(data);
@@ -29,15 +53,12 @@ export function useChainGraphData(props) {
29
53
  data: data,
30
54
  level: level,
31
55
  rootLevel: rootLevel,
32
- getImage: getImage,
33
- isLayouting: function isLayouting(value) {
34
- setIsLayouting(value);
35
- onLayoutingChange === null || onLayoutingChange === void 0 || onLayoutingChange(value);
36
- },
37
- labelRender: labelRender
56
+ getImage: emitImage,
57
+ isLayouting: emitLayouting,
58
+ labelRender: labelRenderRef.current ? renderLabel : undefined
38
59
  });
39
60
  }
40
- }, [graph, data, level, rootLevel, getImage, labelRender, onLayoutingChange, lastData]);
61
+ }, [graph, data, level, rootLevel, lastData, emitImage, emitLayouting, renderLabel, labelRenderRef]);
41
62
  return {
42
63
  isLayouting: isLayouting
43
64
  };
@@ -1,12 +1,23 @@
1
- import { useEffect } from "react";
1
+ import { useCallback, useEffect } from "react";
2
+ import { useLatestRef } from "../../../hooks/useLatestRef";
2
3
  export function useChainGraphLayout(props) {
3
4
  var graph = props.graph,
4
5
  octopus = props.octopus,
5
6
  rootLevel = props.rootLevel,
6
7
  getImage = props.getImage;
8
+
9
+ // getImage 只是「布局完成后把截图 dataURL 交出去」的出口,不是布局的输入。
10
+ // 它进依赖数组会让消费方每传一次内联箭头就重新 changeLayout 一次 —— 整张图重排;
11
+ // 消费方再把截图存进 state,就变成「重排 → 出图 → setState → 新引用 → 再重排」的死循环。
12
+ // 用引用恒定的转发函数注册,调用时再取最新的 getImage。
13
+ var getImageRef = useLatestRef(getImage);
14
+ var emitImage = useCallback(function (img) {
15
+ var _getImageRef$current;
16
+ (_getImageRef$current = getImageRef.current) === null || _getImageRef$current === void 0 || _getImageRef$current.call(getImageRef, img);
17
+ }, [getImageRef]);
7
18
  useEffect(function () {
8
19
  if (graph && octopus !== undefined) {
9
- graph.changeLayout(octopus, rootLevel, getImage);
20
+ graph.changeLayout(octopus, rootLevel, emitImage);
10
21
  }
11
- }, [graph, octopus, rootLevel, getImage]);
22
+ }, [graph, octopus, rootLevel, emitImage]);
12
23
  }
@@ -16,6 +16,7 @@ import { autoScrollByItem } from "../_utils/autoSmooth";
16
16
  import { buildCartesianSeriesOptions, createDefaultCategoryXAxis, createDefaultValueYAxis, getSliderShow, percentWindowToIndexWindow, resolveScrollConfig } from "../_utils/cartesian";
17
17
  import { resolveChartChrome } from "../_utils/chartTheme";
18
18
  import useIsDark from "../../../hooks/useIsDark";
19
+ import useLatestRef from "../../../hooks/useLatestRef";
19
20
  import { jsx as _jsx } from "react/jsx-runtime";
20
21
  var ChartBar = function ChartBar(props) {
21
22
  var className = props.className,
@@ -62,6 +63,30 @@ var ChartBar = function ChartBar(props) {
62
63
  return resolveChartChrome(isDark);
63
64
  }, [isDark]);
64
65
 
66
+ // 回调 prop 一律走 useLatestRef,不进依赖数组:消费方传内联箭头(React 里最常见的
67
+ // 写法)时每次渲染都是新引用,进依赖数组会让「init + setOption(notMerge)」整段重跑,
68
+ // 还会把当前可视窗口再同步一次给父级 —— 父级据此改 state 就是死循环。
69
+ // 但「有没有传回调」决定要不要注册监听,所以单独拆成布尔量进依赖数组,
70
+ // 这样「从无到有传入回调」仍会重新注册,不会漏。
71
+ var onClickRef = useLatestRef(onClick);
72
+ var onLegendSelectChangedRef = useLatestRef(onLegendSelectChanged);
73
+ var onDataZoomWindowChangedRef = useLatestRef(onDataZoomWindowChanged);
74
+ var hasOnClick = !!onClick;
75
+ var hasOnLegendSelectChanged = !!onLegendSelectChanged;
76
+ var hasOnDataZoomWindowChanged = !!onDataZoomWindowChanged;
77
+ // 已通知过父级的窗口用 ref 记账(不参与渲染):窗口没变就不再通知,
78
+ // 掐断「通知 → 父级重算坐标轴 → chartOption 变 → effect 重跑 → 再通知」的自激回路
79
+ var notifiedZoomWindowRef = useRef(null);
80
+ var emitZoomWindow = useCallback(function (next) {
81
+ var _onDataZoomWindowChan;
82
+ var prev = notifiedZoomWindowRef.current;
83
+ if (prev && prev.startIndex === next.startIndex && prev.endIndex === next.endIndex) {
84
+ return;
85
+ }
86
+ notifiedZoomWindowRef.current = next;
87
+ (_onDataZoomWindowChan = onDataZoomWindowChangedRef.current) === null || _onDataZoomWindowChan === void 0 || _onDataZoomWindowChan.call(onDataZoomWindowChangedRef, next);
88
+ }, [onDataZoomWindowChangedRef]);
89
+
65
90
  // Cache the chart option with useMemo
66
91
  var chartOption = useMemo(function () {
67
92
  var _xAxisData$length, _ref, _ref2;
@@ -239,16 +264,16 @@ var ChartBar = function ChartBar(props) {
239
264
  }
240
265
 
241
266
  // Sync the current visible window to the caller (on initial render and after restore), used to recalculate axes based on the displayed portion
242
- if (onDataZoomWindowChanged) {
267
+ if (hasOnDataZoomWindowChanged) {
243
268
  var _chart$getOption3, _xAxisData$length2;
244
269
  var zooms = (_chart$getOption3 = chart.getOption()) === null || _chart$getOption3 === void 0 ? void 0 : _chart$getOption3.dataZoom;
245
270
  var zoom = zooms === null || zooms === void 0 ? void 0 : zooms[0];
246
271
  var totalLen = (_xAxisData$length2 = xAxisData === null || xAxisData === void 0 ? void 0 : xAxisData.length) !== null && _xAxisData$length2 !== void 0 ? _xAxisData$length2 : 0;
247
272
  if (typeof (zoom === null || zoom === void 0 ? void 0 : zoom.start) === "number" && typeof (zoom === null || zoom === void 0 ? void 0 : zoom.end) === "number") {
248
- onDataZoomWindowChanged(percentWindowToIndexWindow(zoom.start, zoom.end, totalLen));
273
+ emitZoomWindow(percentWindowToIndexWindow(zoom.start, zoom.end, totalLen));
249
274
  } else {
250
275
  // Without dataZoom (e.g. scrolling not enabled due to insufficient data) the window is the full range; sync once to avoid a stale old window
251
- onDataZoomWindowChanged({
276
+ emitZoomWindow({
252
277
  startIndex: 0,
253
278
  endIndex: Math.max(0, totalLen - 1)
254
279
  });
@@ -264,17 +289,22 @@ var ChartBar = function ChartBar(props) {
264
289
  resizeObserverRef.current.observe(chartRef.current);
265
290
  }
266
291
 
267
- // Add click event
268
- if (onClick) {
292
+ // Add click event(注册与否看布尔量,实际调用取最新引用)
293
+ var handleClick = function handleClick(event) {
294
+ var _onClickRef$current;
295
+ (_onClickRef$current = onClickRef.current) === null || _onClickRef$current === void 0 || _onClickRef$current.call(onClickRef, event);
296
+ };
297
+ if (hasOnClick) {
269
298
  var _chartInstanceRef$cur2;
270
- (_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click", onClick);
299
+ (_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click", handleClick);
271
300
  }
272
301
 
273
302
  // Legend selection event
274
303
  var handleLegendSelectChanged = function handleLegendSelectChanged(params) {
275
- onLegendSelectChanged === null || onLegendSelectChanged === void 0 || onLegendSelectChanged(params.selected);
304
+ var _onLegendSelectChange;
305
+ (_onLegendSelectChange = onLegendSelectChangedRef.current) === null || _onLegendSelectChange === void 0 || _onLegendSelectChange.call(onLegendSelectChangedRef, params.selected);
276
306
  };
277
- if (onLegendSelectChanged) {
307
+ if (hasOnLegendSelectChanged) {
278
308
  var _chartInstanceRef$cur3;
279
309
  (_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.on("legendselectchanged", handleLegendSelectChanged);
280
310
  }
@@ -285,16 +315,16 @@ var ChartBar = function ChartBar(props) {
285
315
  var raw = params;
286
316
  var info = (_raw$batch$ = raw === null || raw === void 0 || (_raw$batch = raw.batch) === null || _raw$batch === void 0 ? void 0 : _raw$batch[0]) !== null && _raw$batch$ !== void 0 ? _raw$batch$ : raw;
287
317
  if (typeof (info === null || info === void 0 ? void 0 : info.startValue) === "number" && typeof (info === null || info === void 0 ? void 0 : info.endValue) === "number") {
288
- onDataZoomWindowChanged === null || onDataZoomWindowChanged === void 0 || onDataZoomWindowChanged({
318
+ emitZoomWindow({
289
319
  startIndex: Math.max(0, Math.round(info.startValue)),
290
320
  endIndex: Math.max(0, Math.round(info.endValue))
291
321
  });
292
322
  } else if (typeof (info === null || info === void 0 ? void 0 : info.start) === "number" && typeof (info === null || info === void 0 ? void 0 : info.end) === "number") {
293
323
  var _xAxisData$length3;
294
- onDataZoomWindowChanged === null || onDataZoomWindowChanged === void 0 || onDataZoomWindowChanged(percentWindowToIndexWindow(info.start, info.end, (_xAxisData$length3 = xAxisData === null || xAxisData === void 0 ? void 0 : xAxisData.length) !== null && _xAxisData$length3 !== void 0 ? _xAxisData$length3 : 0));
324
+ emitZoomWindow(percentWindowToIndexWindow(info.start, info.end, (_xAxisData$length3 = xAxisData === null || xAxisData === void 0 ? void 0 : xAxisData.length) !== null && _xAxisData$length3 !== void 0 ? _xAxisData$length3 : 0));
295
325
  }
296
326
  };
297
- if (onDataZoomWindowChanged) {
327
+ if (hasOnDataZoomWindowChanged) {
298
328
  var _chartInstanceRef$cur4;
299
329
  (_chartInstanceRef$cur4 = chartInstanceRef.current) === null || _chartInstanceRef$cur4 === void 0 || _chartInstanceRef$cur4.on("datazoom", handleDataZoom);
300
330
  }
@@ -322,15 +352,15 @@ var ChartBar = function ChartBar(props) {
322
352
  // Cleanup function
323
353
  return function () {
324
354
  window.removeEventListener("resize", handleResize);
325
- if (onClick) {
355
+ if (hasOnClick) {
326
356
  var _chartInstanceRef$cur5;
327
- (_chartInstanceRef$cur5 = chartInstanceRef.current) === null || _chartInstanceRef$cur5 === void 0 || _chartInstanceRef$cur5.off("click", onClick);
357
+ (_chartInstanceRef$cur5 = chartInstanceRef.current) === null || _chartInstanceRef$cur5 === void 0 || _chartInstanceRef$cur5.off("click", handleClick);
328
358
  }
329
- if (onLegendSelectChanged) {
359
+ if (hasOnLegendSelectChanged) {
330
360
  var _chartInstanceRef$cur6;
331
361
  (_chartInstanceRef$cur6 = chartInstanceRef.current) === null || _chartInstanceRef$cur6 === void 0 || _chartInstanceRef$cur6.off("legendselectchanged", handleLegendSelectChanged);
332
362
  }
333
- if (onDataZoomWindowChanged) {
363
+ if (hasOnDataZoomWindowChanged) {
334
364
  var _chartInstanceRef$cur7;
335
365
  (_chartInstanceRef$cur7 = chartInstanceRef.current) === null || _chartInstanceRef$cur7 === void 0 || _chartInstanceRef$cur7.off("datazoom", handleDataZoom);
336
366
  }
@@ -339,7 +369,7 @@ var ChartBar = function ChartBar(props) {
339
369
  legendScrollRef.current = null;
340
370
  }
341
371
  };
342
- }, [chartOption, handleResize, onClick, onLegendSelectChanged, onDataZoomWindowChanged, xAxisData, enableLegendAutoScroll, legendVisibleCount, legendScrollInterval,
372
+ }, [chartOption, handleResize, onClickRef, onLegendSelectChangedRef, hasOnClick, hasOnLegendSelectChanged, hasOnDataZoomWindowChanged, emitZoomWindow, xAxisData, enableLegendAutoScroll, legendVisibleCount, legendScrollInterval,
343
373
  // 图例是否接管滚轮由它推导,漏了会拿到过期的滚动配置
344
374
  normalizedScroll, containerReady]);
345
375
 
@@ -359,13 +389,13 @@ var ChartBar = function ChartBar(props) {
359
389
  startIndex: normalizedScroll.startIndex,
360
390
  autoPlay: normalizedScroll.autoScroll,
361
391
  enableWheelScroll: enableWheelScroll,
362
- onWindowChange: onDataZoomWindowChanged ? function (startPercent, endPercent) {
363
- return onDataZoomWindowChanged(percentWindowToIndexWindow(startPercent, endPercent, xAxisData.length));
392
+ onWindowChange: hasOnDataZoomWindowChanged ? function (startPercent, endPercent) {
393
+ return emitZoomWindow(percentWindowToIndexWindow(startPercent, endPercent, xAxisData.length));
364
394
  } : undefined
365
395
  }),
366
396
  dispose = _autoScrollByItem.dispose;
367
397
  return dispose;
368
- }, [dataZoom, normalizedScroll, sliderDataZoom, xAxisData, onDataZoomWindowChanged]);
398
+ }, [dataZoom, normalizedScroll, sliderDataZoom, xAxisData, hasOnDataZoomWindowChanged, emitZoomWindow]);
369
399
 
370
400
  // Clean up resources when the component unmounts
371
401
  useEffect(function () {
@@ -21,6 +21,7 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"
21
21
  import styles from "../index.module.scss";
22
22
  import * as echarts from "echarts";
23
23
  import { defaultBubbleColorList, drawCircles } from "../_utils/bubble";
24
+ import { useLatestRef } from "../../../hooks/useLatestRef";
24
25
 
25
26
  // Extended data item type containing all properties the chart needs
26
27
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -276,7 +277,16 @@ var Bubble = function Bubble(props) {
276
277
  chartInstanceRef.current.setOption(chartOption, true);
277
278
  }
278
279
  }, [chartOption, data]);
280
+ var onChartRef = useLatestRef(onChart);
279
281
 
282
+ // onClick 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 跟着重跑就会
283
+ // 再走一遍 setOption(notMerge),动画重播、悬浮/高亮态被清掉。注册与否看布尔量,
284
+ // 这样「从无到有传入 onClick」仍会注册;实际调用取 ref 里的最新引用。
285
+ var onClickRef = useLatestRef(onClick);
286
+ var hasOnClick = !!onClick;
287
+
288
+ // 回调 prop 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 会跟着
289
+ // 重跑并再调一次回调 —— 回调里 setState 就是死循环(详见 Input/TextArea 的说明)
280
290
  // Initialize the chart
281
291
  useEffect(function () {
282
292
  if (!chartRef.current) return;
@@ -286,10 +296,11 @@ var Bubble = function Bubble(props) {
286
296
  // Initialize or reuse the existing instance
287
297
  var chart = chartInstanceRef.current;
288
298
  if (!chart) {
299
+ var _onChartRef$current;
289
300
  chart = echarts.init(chartRef.current);
290
301
  chartInstanceRef.current = chart;
291
302
  // Call the onChart callback on first initialization
292
- onChart === null || onChart === void 0 || onChart(chart);
303
+ (_onChartRef$current = onChartRef.current) === null || _onChartRef$current === void 0 || _onChartRef$current.call(onChartRef, chart);
293
304
  }
294
305
 
295
306
  // Resize first so echarts picks up the correct container size, then apply the option
@@ -300,20 +311,24 @@ var Bubble = function Bubble(props) {
300
311
  window.addEventListener("resize", handleResize);
301
312
 
302
313
  // Add click event
303
- if (onClick) {
314
+ var handleClick = function handleClick(event) {
315
+ var _onClickRef$current;
316
+ (_onClickRef$current = onClickRef.current) === null || _onClickRef$current === void 0 || _onClickRef$current.call(onClickRef, event);
317
+ };
318
+ if (hasOnClick) {
304
319
  var _chartInstanceRef$cur2;
305
- (_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click", onClick);
320
+ (_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click", handleClick);
306
321
  }
307
322
 
308
323
  // Cleanup function
309
324
  return function () {
310
325
  window.removeEventListener("resize", handleResize);
311
- if (onClick) {
326
+ if (hasOnClick) {
312
327
  var _chartInstanceRef$cur3;
313
- (_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.off("click", onClick);
328
+ (_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.off("click", handleClick);
314
329
  }
315
330
  };
316
- }, [chartOption, containerSize.width, containerSize.height, handleResize, onChart, onClick]);
331
+ }, [chartOption, containerSize.width, containerSize.height, handleResize, onChartRef, onClickRef, hasOnClick]);
317
332
 
318
333
  // Dispose the chart instance when the component unmounts
319
334
  useEffect(function () {
@@ -11,6 +11,7 @@ import React, { useCallback, useEffect, useMemo, useRef } from "react";
11
11
  import useContainerReady from "../_hooks/useContainerReady";
12
12
  import styles from "../index.module.scss";
13
13
  import * as echarts from "echarts";
14
+ import { useLatestRef } from "../../../hooks/useLatestRef";
14
15
  import { jsx as _jsx } from "react/jsx-runtime";
15
16
  var Common = function Common(props) {
16
17
  var className = props.className,
@@ -38,9 +39,13 @@ var Common = function Common(props) {
38
39
  if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
39
40
  (_chartInstanceRef$cur = chartInstanceRef.current) === null || _chartInstanceRef$cur === void 0 || _chartInstanceRef$cur.resize();
40
41
  }, []);
42
+ var onChartRef = useLatestRef(onChart);
41
43
 
44
+ // 回调 prop 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 会跟着
45
+ // 重跑并再调一次回调 —— 回调里 setState 就是死循环(详见 Input/TextArea 的说明)
42
46
  // Initialize the chart
43
47
  useEffect(function () {
48
+ var _onChartRef$current;
44
49
  if (!chartRef.current || !containerReady) return;
45
50
 
46
51
  // Initialize or reuse an existing instance
@@ -54,7 +59,7 @@ var Common = function Common(props) {
54
59
  chart.setOption(chartOption, true);
55
60
 
56
61
  // Chart-ready callback (can be used for legend auto-scroll, etc.)
57
- onChart === null || onChart === void 0 || onChart(chart);
62
+ (_onChartRef$current = onChartRef.current) === null || _onChartRef$current === void 0 || _onChartRef$current.call(onChartRef, chart);
58
63
 
59
64
  // Add resize listener
60
65
  window.addEventListener("resize", handleResize);
@@ -69,7 +74,7 @@ var Common = function Common(props) {
69
74
  return function () {
70
75
  window.removeEventListener("resize", handleResize);
71
76
  };
72
- }, [chartOption, handleResize, onChart, containerReady]);
77
+ }, [chartOption, handleResize, onChartRef, containerReady]);
73
78
 
74
79
  // Clean up resources on component unmount
75
80
  useEffect(function () {
@@ -20,6 +20,7 @@ import * as echarts from "echarts";
20
20
  import { createDefaultHeatmapXAxis, createDefaultHeatmapYAxis } from "../_utils/heatmap";
21
21
  import { resolveChartChrome } from "../_utils/chartTheme";
22
22
  import useIsDark from "../../../hooks/useIsDark";
23
+ import { useLatestRef } from "../../../hooks/useLatestRef";
23
24
  import { jsx as _jsx } from "react/jsx-runtime";
24
25
  var Heatmap = function Heatmap(props) {
25
26
  var className = props.className,
@@ -192,7 +193,16 @@ var Heatmap = function Heatmap(props) {
192
193
  if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
193
194
  (_chartInstanceRef$cur = chartInstanceRef.current) === null || _chartInstanceRef$cur === void 0 || _chartInstanceRef$cur.resize();
194
195
  }, []);
196
+ var onChartRef = useLatestRef(onChart);
195
197
 
198
+ // onClick 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 跟着重跑就会
199
+ // 再走一遍 setOption(notMerge),动画重播、悬浮/高亮态被清掉。注册与否看布尔量,
200
+ // 这样「从无到有传入 onClick」仍会注册;实际调用取 ref 里的最新引用。
201
+ var onClickRef = useLatestRef(onClick);
202
+ var hasOnClick = !!onClick;
203
+
204
+ // 回调 prop 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 会跟着
205
+ // 重跑并再调一次回调 —— 回调里 setState 就是死循环(详见 Input/TextArea 的说明)
196
206
  // Initialize the chart
197
207
  useEffect(function () {
198
208
  if (!chartRef.current || !containerReady) return;
@@ -200,10 +210,11 @@ var Heatmap = function Heatmap(props) {
200
210
  // Initialize or reuse the existing instance
201
211
  var chart = chartInstanceRef.current;
202
212
  if (!chart) {
213
+ var _onChartRef$current;
203
214
  chart = echarts.init(chartRef.current);
204
215
  chartInstanceRef.current = chart;
205
216
  // Call the onChart callback on first initialization
206
- onChart === null || onChart === void 0 || onChart(chart);
217
+ (_onChartRef$current = onChartRef.current) === null || _onChartRef$current === void 0 || _onChartRef$current.call(onChartRef, chart);
207
218
  }
208
219
 
209
220
  // Apply the option
@@ -219,20 +230,24 @@ var Heatmap = function Heatmap(props) {
219
230
  }
220
231
 
221
232
  // Add click event
222
- if (onClick) {
233
+ var handleClick = function handleClick(event) {
234
+ var _onClickRef$current;
235
+ (_onClickRef$current = onClickRef.current) === null || _onClickRef$current === void 0 || _onClickRef$current.call(onClickRef, event);
236
+ };
237
+ if (hasOnClick) {
223
238
  var _chartInstanceRef$cur2;
224
- (_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click", onClick);
239
+ (_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click", handleClick);
225
240
  }
226
241
 
227
242
  // Cleanup function
228
243
  return function () {
229
244
  window.removeEventListener("resize", handleResize);
230
- if (onClick) {
245
+ if (hasOnClick) {
231
246
  var _chartInstanceRef$cur3;
232
- (_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.off("click", onClick);
247
+ (_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.off("click", handleClick);
233
248
  }
234
249
  };
235
- }, [chartOption, handleResize, onChart, onClick, containerReady]);
250
+ }, [chartOption, handleResize, onChartRef, onClickRef, hasOnClick, containerReady]);
236
251
 
237
252
  // Clean up resources when the component unmounts
238
253
  useEffect(function () {
@@ -16,6 +16,7 @@ import { autoScrollByItem } from "../_utils/autoSmooth";
16
16
  import { buildCartesianSeriesOptions, createDefaultCategoryXAxis, createDefaultValueYAxis, getSliderShow, percentWindowToIndexWindow, resolveScrollConfig } from "../_utils/cartesian";
17
17
  import { resolveChartChrome } from "../_utils/chartTheme";
18
18
  import useIsDark from "../../../hooks/useIsDark";
19
+ import useLatestRef from "../../../hooks/useLatestRef";
19
20
  import { jsx as _jsx } from "react/jsx-runtime";
20
21
  var ChartLine = function ChartLine(props) {
21
22
  var className = props.className,
@@ -62,6 +63,30 @@ var ChartLine = function ChartLine(props) {
62
63
  return resolveChartChrome(isDark);
63
64
  }, [isDark]);
64
65
 
66
+ // 回调 prop 一律走 useLatestRef,不进依赖数组:消费方传内联箭头(React 里最常见的
67
+ // 写法)时每次渲染都是新引用,进依赖数组会让「init + setOption(notMerge)」整段重跑,
68
+ // 还会把当前可视窗口再同步一次给父级 —— 父级据此改 state 就是死循环。
69
+ // 但「有没有传回调」决定要不要注册监听,所以单独拆成布尔量进依赖数组,
70
+ // 这样「从无到有传入回调」仍会重新注册,不会漏。
71
+ var onClickRef = useLatestRef(onClick);
72
+ var onLegendSelectChangedRef = useLatestRef(onLegendSelectChanged);
73
+ var onDataZoomWindowChangedRef = useLatestRef(onDataZoomWindowChanged);
74
+ var hasOnClick = !!onClick;
75
+ var hasOnLegendSelectChanged = !!onLegendSelectChanged;
76
+ var hasOnDataZoomWindowChanged = !!onDataZoomWindowChanged;
77
+ // 已通知过父级的窗口用 ref 记账(不参与渲染):窗口没变就不再通知,
78
+ // 掐断「通知 → 父级重算坐标轴 → chartOption 变 → effect 重跑 → 再通知」的自激回路
79
+ var notifiedZoomWindowRef = useRef(null);
80
+ var emitZoomWindow = useCallback(function (next) {
81
+ var _onDataZoomWindowChan;
82
+ var prev = notifiedZoomWindowRef.current;
83
+ if (prev && prev.startIndex === next.startIndex && prev.endIndex === next.endIndex) {
84
+ return;
85
+ }
86
+ notifiedZoomWindowRef.current = next;
87
+ (_onDataZoomWindowChan = onDataZoomWindowChangedRef.current) === null || _onDataZoomWindowChan === void 0 || _onDataZoomWindowChan.call(onDataZoomWindowChangedRef, next);
88
+ }, [onDataZoomWindowChangedRef]);
89
+
65
90
  // Cache the chart option with useMemo
66
91
  var chartOption = useMemo(function () {
67
92
  var _xAxisData$length, _ref, _ref2;
@@ -236,16 +261,16 @@ var ChartLine = function ChartLine(props) {
236
261
  }
237
262
 
238
263
  // Sync the current visible window to the caller (on initial render and after restore), used to recalculate axes based on the displayed portion
239
- if (onDataZoomWindowChanged) {
264
+ if (hasOnDataZoomWindowChanged) {
240
265
  var _chart$getOption3, _xAxisData$length2;
241
266
  var zooms = (_chart$getOption3 = chart.getOption()) === null || _chart$getOption3 === void 0 ? void 0 : _chart$getOption3.dataZoom;
242
267
  var zoom = zooms === null || zooms === void 0 ? void 0 : zooms[0];
243
268
  var totalLen = (_xAxisData$length2 = xAxisData === null || xAxisData === void 0 ? void 0 : xAxisData.length) !== null && _xAxisData$length2 !== void 0 ? _xAxisData$length2 : 0;
244
269
  if (typeof (zoom === null || zoom === void 0 ? void 0 : zoom.start) === "number" && typeof (zoom === null || zoom === void 0 ? void 0 : zoom.end) === "number") {
245
- onDataZoomWindowChanged(percentWindowToIndexWindow(zoom.start, zoom.end, totalLen));
270
+ emitZoomWindow(percentWindowToIndexWindow(zoom.start, zoom.end, totalLen));
246
271
  } else {
247
272
  // Without dataZoom (e.g. scrolling not enabled due to insufficient data) the window is the full range; sync once to avoid a stale old window
248
- onDataZoomWindowChanged({
273
+ emitZoomWindow({
249
274
  startIndex: 0,
250
275
  endIndex: Math.max(0, totalLen - 1)
251
276
  });
@@ -261,17 +286,22 @@ var ChartLine = function ChartLine(props) {
261
286
  resizeObserverRef.current.observe(chartRef.current);
262
287
  }
263
288
 
264
- // Add click event
265
- if (onClick) {
289
+ // Add click event(注册与否看布尔量,实际调用取最新引用)
290
+ var handleClick = function handleClick(event) {
291
+ var _onClickRef$current;
292
+ (_onClickRef$current = onClickRef.current) === null || _onClickRef$current === void 0 || _onClickRef$current.call(onClickRef, event);
293
+ };
294
+ if (hasOnClick) {
266
295
  var _chartInstanceRef$cur2;
267
- (_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click", onClick);
296
+ (_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click", handleClick);
268
297
  }
269
298
 
270
299
  // Legend selection event
271
300
  var handleLegendSelectChanged = function handleLegendSelectChanged(params) {
272
- onLegendSelectChanged === null || onLegendSelectChanged === void 0 || onLegendSelectChanged(params.selected);
301
+ var _onLegendSelectChange;
302
+ (_onLegendSelectChange = onLegendSelectChangedRef.current) === null || _onLegendSelectChange === void 0 || _onLegendSelectChange.call(onLegendSelectChangedRef, params.selected);
273
303
  };
274
- if (onLegendSelectChanged) {
304
+ if (hasOnLegendSelectChanged) {
275
305
  var _chartInstanceRef$cur3;
276
306
  (_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.on("legendselectchanged", handleLegendSelectChanged);
277
307
  }
@@ -282,16 +312,16 @@ var ChartLine = function ChartLine(props) {
282
312
  var raw = params;
283
313
  var info = (_raw$batch$ = raw === null || raw === void 0 || (_raw$batch = raw.batch) === null || _raw$batch === void 0 ? void 0 : _raw$batch[0]) !== null && _raw$batch$ !== void 0 ? _raw$batch$ : raw;
284
314
  if (typeof (info === null || info === void 0 ? void 0 : info.startValue) === "number" && typeof (info === null || info === void 0 ? void 0 : info.endValue) === "number") {
285
- onDataZoomWindowChanged === null || onDataZoomWindowChanged === void 0 || onDataZoomWindowChanged({
315
+ emitZoomWindow({
286
316
  startIndex: Math.max(0, Math.round(info.startValue)),
287
317
  endIndex: Math.max(0, Math.round(info.endValue))
288
318
  });
289
319
  } else if (typeof (info === null || info === void 0 ? void 0 : info.start) === "number" && typeof (info === null || info === void 0 ? void 0 : info.end) === "number") {
290
320
  var _xAxisData$length3;
291
- onDataZoomWindowChanged === null || onDataZoomWindowChanged === void 0 || onDataZoomWindowChanged(percentWindowToIndexWindow(info.start, info.end, (_xAxisData$length3 = xAxisData === null || xAxisData === void 0 ? void 0 : xAxisData.length) !== null && _xAxisData$length3 !== void 0 ? _xAxisData$length3 : 0));
321
+ emitZoomWindow(percentWindowToIndexWindow(info.start, info.end, (_xAxisData$length3 = xAxisData === null || xAxisData === void 0 ? void 0 : xAxisData.length) !== null && _xAxisData$length3 !== void 0 ? _xAxisData$length3 : 0));
292
322
  }
293
323
  };
294
- if (onDataZoomWindowChanged) {
324
+ if (hasOnDataZoomWindowChanged) {
295
325
  var _chartInstanceRef$cur4;
296
326
  (_chartInstanceRef$cur4 = chartInstanceRef.current) === null || _chartInstanceRef$cur4 === void 0 || _chartInstanceRef$cur4.on("datazoom", handleDataZoom);
297
327
  }
@@ -319,15 +349,15 @@ var ChartLine = function ChartLine(props) {
319
349
  // Cleanup function
320
350
  return function () {
321
351
  window.removeEventListener("resize", handleResize);
322
- if (onClick) {
352
+ if (hasOnClick) {
323
353
  var _chartInstanceRef$cur5;
324
- (_chartInstanceRef$cur5 = chartInstanceRef.current) === null || _chartInstanceRef$cur5 === void 0 || _chartInstanceRef$cur5.off("click", onClick);
354
+ (_chartInstanceRef$cur5 = chartInstanceRef.current) === null || _chartInstanceRef$cur5 === void 0 || _chartInstanceRef$cur5.off("click", handleClick);
325
355
  }
326
- if (onLegendSelectChanged) {
356
+ if (hasOnLegendSelectChanged) {
327
357
  var _chartInstanceRef$cur6;
328
358
  (_chartInstanceRef$cur6 = chartInstanceRef.current) === null || _chartInstanceRef$cur6 === void 0 || _chartInstanceRef$cur6.off("legendselectchanged", handleLegendSelectChanged);
329
359
  }
330
- if (onDataZoomWindowChanged) {
360
+ if (hasOnDataZoomWindowChanged) {
331
361
  var _chartInstanceRef$cur7;
332
362
  (_chartInstanceRef$cur7 = chartInstanceRef.current) === null || _chartInstanceRef$cur7 === void 0 || _chartInstanceRef$cur7.off("datazoom", handleDataZoom);
333
363
  }
@@ -336,7 +366,7 @@ var ChartLine = function ChartLine(props) {
336
366
  legendScrollRef.current = null;
337
367
  }
338
368
  };
339
- }, [chartOption, handleResize, onClick, onLegendSelectChanged, onDataZoomWindowChanged, xAxisData, enableLegendAutoScroll, legendVisibleCount, legendScrollInterval,
369
+ }, [chartOption, handleResize, onClickRef, onLegendSelectChangedRef, hasOnClick, hasOnLegendSelectChanged, hasOnDataZoomWindowChanged, emitZoomWindow, xAxisData, enableLegendAutoScroll, legendVisibleCount, legendScrollInterval,
340
370
  // 图例是否接管滚轮由它推导,漏了会拿到过期的滚动配置
341
371
  normalizedScroll, containerReady]);
342
372
 
@@ -356,13 +386,13 @@ var ChartLine = function ChartLine(props) {
356
386
  startIndex: normalizedScroll.startIndex,
357
387
  autoPlay: normalizedScroll.autoScroll,
358
388
  enableWheelScroll: enableWheelScroll,
359
- onWindowChange: onDataZoomWindowChanged ? function (startPercent, endPercent) {
360
- return onDataZoomWindowChanged(percentWindowToIndexWindow(startPercent, endPercent, xAxisData.length));
389
+ onWindowChange: hasOnDataZoomWindowChanged ? function (startPercent, endPercent) {
390
+ return emitZoomWindow(percentWindowToIndexWindow(startPercent, endPercent, xAxisData.length));
361
391
  } : undefined
362
392
  }),
363
393
  dispose = _autoScrollByItem.dispose;
364
394
  return dispose;
365
- }, [dataZoom, normalizedScroll, sliderDataZoom, xAxisData, onDataZoomWindowChanged]);
395
+ }, [dataZoom, normalizedScroll, sliderDataZoom, xAxisData, hasOnDataZoomWindowChanged, emitZoomWindow]);
366
396
 
367
397
  // Clean up resources when the component unmounts
368
398
  useEffect(function () {
@@ -8,6 +8,7 @@ import React, { useCallback, useEffect, useMemo, useRef } from "react";
8
8
  import { useMouseOverHandler, useGlobalOutHandler } from "./_hooks";
9
9
  import { getPie3DOption } from "./_utils/option";
10
10
  import styles from "../../index.module.scss";
11
+ import { useLatestRef } from "../../../../hooks/useLatestRef";
11
12
  import { jsx as _jsx } from "react/jsx-runtime";
12
13
  var ChartPie3D = function ChartPie3D(props) {
13
14
  var className = props.className,
@@ -89,13 +90,24 @@ var ChartPie3D = function ChartPie3D(props) {
89
90
  yOffset: yOffset,
90
91
  autoRotate: autoRotate
91
92
  });
93
+ var onChartRef = useLatestRef(onChart);
94
+
95
+ // onClick 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 跟着重跑会重建
96
+ // 3D 饼的 option 并重播动画。注册与否看布尔量(保证「从无到有传入」仍会注册),
97
+ // 实际调用取 ref 里的最新引用。
98
+ var onClickRef = useLatestRef(onClick);
99
+ var hasOnClick = !!onClick;
100
+
101
+ // 回调 prop 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 会跟着
102
+ // 重跑并再调一次回调 —— 回调里 setState 就是死循环(详见 Input/TextArea 的说明)
92
103
  useEffect(function () {
93
104
  if (!chartRef.current || !containerReady) return;
94
105
  var chart = chartInstanceRef.current;
95
106
  if (!chart) {
107
+ var _onChartRef$current;
96
108
  chart = echarts.init(chartRef.current);
97
109
  chartInstanceRef.current = chart;
98
- onChart === null || onChart === void 0 || onChart(chart);
110
+ (_onChartRef$current = onChartRef.current) === null || _onChartRef$current === void 0 || _onChartRef$current.call(onChartRef, chart);
99
111
  }
100
112
  chart.setOption(chartOption, true);
101
113
  optionRef.current = chartOption;
@@ -106,20 +118,24 @@ var ChartPie3D = function ChartPie3D(props) {
106
118
  }
107
119
  chart.on("mouseover", handleMouseOver);
108
120
  chart.on("globalout", handleGlobalOut);
109
- if (onClick) {
110
- chart.on("click", onClick);
121
+ var handleClick = function handleClick(event) {
122
+ var _onClickRef$current;
123
+ (_onClickRef$current = onClickRef.current) === null || _onClickRef$current === void 0 || _onClickRef$current.call(onClickRef, event);
124
+ };
125
+ if (hasOnClick) {
126
+ chart.on("click", handleClick);
111
127
  }
112
128
  return function () {
113
129
  window.removeEventListener("resize", handleResize);
114
130
  if (chart) {
115
131
  chart.off("mouseover", handleMouseOver);
116
132
  chart.off("globalout", handleGlobalOut);
117
- if (onClick) {
118
- chart.off("click", onClick);
133
+ if (hasOnClick) {
134
+ chart.off("click", handleClick);
119
135
  }
120
136
  }
121
137
  };
122
- }, [chartOption, handleResize, handleMouseOver, handleGlobalOut, onChart, onClick, containerReady]);
138
+ }, [chartOption, handleResize, handleMouseOver, handleGlobalOut, onChartRef, onClickRef, hasOnClick, containerReady]);
123
139
  useEffect(function () {
124
140
  return function () {
125
141
  if (resizeObserverRef.current) {