react-resizable-panels icon indicating copy to clipboard operation
react-resizable-panels copied to clipboard

[bug]: Resizable dragging caused Max Depth Exceeded in ReactJS

Open luobo17 opened this issue 11 months ago • 9 comments

Describe the bug

console error of

react-dom.development.js:26793 Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops. was observed when I was dragging the ResizableHandler left and right multiple times.

Affected component/components

Resizable

How to reproduce

/package.json: "react-resizable-panels": "^2.1.7", ...

Logs

react-dom.development.js:26793 Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
at throwIfInfiniteUpdateLoopDetected (react-dom.development.js:26793:11)
    at getRootForUpdatedFiber (react-dom.development.js:7627:3)
    at enqueueConcurrentHookUpdate (react-dom.development.js:7518:10)
    at dispatchSetState (react-dom.development.js:13073:16)
    at resizeHandler (react-resizable-panels.browser.development.esm.js:2122:9)
    at setResizeHandlerState (react-resizable-panels.browser.development.esm.js:2449:15)
    at eval (react-resizable-panels.browser.development.esm.js:715:5)
    at Set.forEach (<anonymous>)
    at updateResizeHandlerStates (react-resizable-panels.browser.development.esm.js:710:28)
    at HTMLBodyElement.handlePointerMove (...

Thoughts

In react-resizable-panels.development.node.esm.js:

const resizeHandleId = useUniqueId(idFromProps);
const [state, setState] = useState("inactive");
const [isFocused, setIsFocused] = useState(false);
const [resizeHandler, setResizeHandler] = useState(null);
const committedValuesRef = useRef({
  state
});
useEffect(() => {
  if (disabled) {
    setResizeHandler(null);
  } else {
    const resizeHandler = registerResizeHandleWithParentGroup(resizeHandleId);
    setResizeHandler(() => resizeHandler);
  }
}, [disabled, resizeHandleId, registerResizeHandleWithParentGroup]);

System Info

Tried both Arc and Chrome browsers, got the same error.

Before submitting

  • [X] I've made research efforts and searched the documentation
  • [X] I've searched for existing issues

luobo17 avatar Mar 12 '25 10:03 luobo17

I faced the same issue here. Is there a way for me to open a bounty for this?

lawrencenika avatar Mar 13 '25 02:03 lawrencenika

Haven’t been asked that before and don’t know the answer, but if you have a suggestion feel free to share.

React and ReactDOM versions are missing from this issue, as well as operating system and browser versions.

bvaughn avatar Mar 13 '25 09:03 bvaughn

for me it was [email protected], [email protected], macOs, Arc. I tried Chrome just now too, same issue.

lawrencenika avatar Mar 13 '25 09:03 lawrencenika

we hit the same issue with [email protected] + [email protected] using brave on macOS.

ImLunaHey avatar May 30 '25 12:05 ImLunaHey

the cause for us seems to point to the following scenario.

  1. The ResizeObserver observes the panel group element
  2. When the panel group resizes, it triggers the callback
  3. The callback calculates new percentages and updates state
  4. The state updates cause a re-render
  5. This might trigger another resize event, starting the cycle again

ImLunaHey avatar May 30 '25 12:05 ImLunaHey

@ImLunaHey I would be happy to review a PR if you’d like to propose a fix.

bvaughn avatar May 30 '25 13:05 bvaughn

i dont think anything needs to be changed in this library. i believe this is us consuming it incorrectly. the above is to do with how we use it internally at work. (we caused the problem)

ImLunaHey avatar May 30 '25 15:05 ImLunaHey

I see. Thanks for the info!

bvaughn avatar May 31 '25 12:05 bvaughn

I'm seeing a similar error to this where my tests failed after enabling draggable for PanelHandle. It appears that the calculation of layout in the background triggers another cycle of state updates. As a workaround for production, I have to conditionally do this: <PanelResizeHandle draggable={process.env.NODE_ENV !== "test"}.

My attempts:

  • Used waitFor for render before finding the elements --> Got timeout
  • Used act --> Did not work
Image Image

duynguyen-kun avatar Jul 11 '25 06:07 duynguyen-kun