Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proxyObject will cause "maximum depth exceeded error" when it's working with libs like @radix-ui/react-tooltip due to operations like forwardRef & composeRef. #664

Open
dontbmh opened this issue Aug 6, 2024 · 1 comment

Comments

@dontbmh
Copy link

dontbmh commented Aug 6, 2024

Hi! 👋

Firstly, thanks for your work on this project! 🙂

Today I used patch-package to patch [email protected] for the project I'm working on.

Here is the diff that solved my problem:

diff --git a/node_modules/rc-input-number/es/InputNumber.js b/node_modules/rc-input-number/es/InputNumber.js
index 5831c16..f2dc7f1 100644
--- a/node_modules/rc-input-number/es/InputNumber.js
+++ b/node_modules/rc-input-number/es/InputNumber.js
@@ -1,22 +1,21 @@
-import _extends from "@babel/runtime/helpers/esm/extends";
 import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
-import _typeof from "@babel/runtime/helpers/esm/typeof";
-import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
+import _extends from "@babel/runtime/helpers/esm/extends";
 import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
-var _excluded = ["prefixCls", "className", "style", "min", "max", "step", "defaultValue", "value", "disabled", "readOnly", "upHandler", "downHandler", "keyboard", "changeOnWheel", "controls", "classNames", "stringMode", "parser", "formatter", "precision", "decimalSeparator", "onChange", "onInput", "onPressEnter", "onStep", "changeOnBlur", "domRef"],
-  _excluded2 = ["disabled", "style", "prefixCls", "value", "prefix", "suffix", "addonBefore", "addonAfter", "className", "classNames"];
+import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
+import _typeof from "@babel/runtime/helpers/esm/typeof";
 import getMiniDecimal, { getNumberPrecision, num2str, toFixed, validateNumber } from '@rc-component/mini-decimal';
 import clsx from 'classnames';
 import { BaseInput } from 'rc-input';
+import { triggerFocus } from "rc-input/es/utils/commonUtils";
 import { useLayoutUpdateEffect } from "rc-util/es/hooks/useLayoutEffect";
-import proxyObject from "rc-util/es/proxyObject";
 import { composeRef } from "rc-util/es/ref";
 import * as React from 'react';
 import useCursor from "./hooks/useCursor";
+import useFrame from "./hooks/useFrame";
 import StepHandler from "./StepHandler";
 import { getDecupleSteps } from "./utils/numberUtil";
-import { triggerFocus } from "rc-input/es/utils/commonUtils";
-import useFrame from "./hooks/useFrame";
+var _excluded = ["prefixCls", "className", "style", "min", "max", "step", "defaultValue", "value", "disabled", "readOnly", "upHandler", "downHandler", "keyboard", "changeOnWheel", "controls", "classNames", "stringMode", "parser", "formatter", "precision", "decimalSeparator", "onChange", "onInput", "onPressEnter", "onStep", "changeOnBlur", "domRef"],
+  _excluded2 = ["disabled", "style", "prefixCls", "value", "prefix", "suffix", "addonBefore", "addonAfter", "className", "classNames"];
 /**
  * We support `stringMode` which need handle correct type when user call in onChange
  * format max or min value
@@ -536,9 +535,10 @@ var InputNumber = /*#__PURE__*/React.forwardRef(function (props, ref) {
     }
   };
   React.useImperativeHandle(ref, function () {
-    return proxyObject(inputFocusRef.current, {
-      nativeElement: holderRef.current.nativeElement || inputNumberDomRef.current
-    });
+    if(inputFocusRef.current) {
+      inputFocusRef.current.nativeElement = holderRef.current.nativeElement || inputNumberDomRef.current;
+    }
+    return inputFocusRef.current
   });
   return /*#__PURE__*/React.createElement(BaseInput, {
     className: className,
diff --git a/node_modules/rc-input-number/lib/InputNumber.js b/node_modules/rc-input-number/lib/InputNumber.js
index 14b07f8..a0f0b65 100644
--- a/node_modules/rc-input-number/lib/InputNumber.js
+++ b/node_modules/rc-input-number/lib/InputNumber.js
@@ -546,9 +546,10 @@ var InputNumber = /*#__PURE__*/React.forwardRef(function (props, ref) {
     }
   };
   React.useImperativeHandle(ref, function () {
-    return (0, _proxyObject.default)(inputFocusRef.current, {
-      nativeElement: holderRef.current.nativeElement || inputNumberDomRef.current
-    });
+    if(inputFocusRef.current) {
+      inputFocusRef.current.nativeElement = holderRef.current.nativeElement || inputNumberDomRef.current;
+    }
+    return inputFocusRef.current
   });
   return /*#__PURE__*/React.createElement(_rcInput.BaseInput, {
     className: className,

This issue body was partially generated by patch-package.

@towertop
Copy link

@dontbmh maybe u were suffering same issue as me. I came to identical React error when upgrade repo to antd 5.23 and only when making a pattern like <Tooltip><InputNumber/><Tooltip>. I found the cuase is the mistakenly resolved rc-util old version which often happen when your repo have many deps from antd ecosystem.

Here is the simplified error trace:

  1. antd's InputNumber and the underneath rc-input-number hijacked the forward ref with creating a new Proxy every invocation:
    https://github.com/react-component/input-number/blob/master/src/InputNumber.tsx#L665

  2. Tooltip and the underneath rc-trigger has a dirty check and setState logic which would fall into trap if received a new Proxy object every round:
    https://github.com/react-component/trigger/blob/master/src/index.tsx#L264

  3. The forwarded ref result is transported by rc-resize-observer leverage multiple rc-util functions:
    https://github.com/react-component/resize-observer/blob/master/src/SingleObserver/index.tsx#L37

  4. And the broken point came when your repo using a legacy rc-util version before v5.40 where they add a new logic to unwrap the original HTML element by nativeElement instead passing by the Proxy object:
    https://github.com/react-component/util/blob/v5.39.3/src/Dom/findDOMNode.ts
    https://github.com/react-component/util/blob/master/src/Dom/findDOMNode.ts

I think the better fix is to confirm the resolved rc-util version from yarn.lock or node_modules on disk, and use resolutions section of package.json to correct it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants