Versions: recharts 3.9.2, React 19.2.5, Next.js 16.2.10 (Turbopack), Chrome.
Setup: an AreaChart/LineChart inside ResponsiveContainer with XAxis, YAxis, Tooltip, CartesianGrid, and a few ReferenceLines. The parent component re-renders in response to a range slider (an "as of" time scrubber): each input event calls setState, which recomputes the chart's data array and a ReferenceLine x.
Problem 1 — hard crash under fast scrubbing. With the app calling setState once per slider input event (no throttling), a fast mouse drag (input events arrive faster than frame rate) trips React's nested update limit:
Error: Maximum update depth exceeded. ...
The above error occurred in the <RenderedTicksReporter> component.
Captured stack: RenderedTicksReporter.useEffect → store dispatch → notifyNestedSubs → forceStoreRerender, firing during commitPassiveUnmountOnFiber, interleaved with the app's own dispatchSetState per slider event until the 50 nested update limit throws. In development this crashes the route to the nearest error boundary at genuine human drag speed; in a production build the same crash (minified React #185) reproduces under higher-rate event bursts.
Problem 2 — the dev warning floor. After fixing the app side — coalescing slider updates to one setState per animation frame, hoisting every static prop to module constants (margin, axisLine, tickFormatter, label objects), and memoizing the ReferenceLine elements so only genuinely data-driven props change identity — the crash is gone at any input rate. But during continuous scrubbing the dev-only "Maximum update depth exceeded" console.error still fires roughly once per 50 frames: each frame's legitimate data change (new data array + ReferenceLine x) is followed by at least one nested store dispatch from a recharts passive effect, so React's nested update counter never sees a quiet frame to reset.
Question/ask: could the axis/tick settings sync (and RenderedTicksReporter) skip dispatching when the incoming settings are value-equal to the stored ones, rather than reference-equal? That would let data-driven re-renders (animation/scrubbing use cases) complete without a nested store dispatch per frame, which both removes the dev warning floor and adds headroom against the hard crash for apps that haven't frame-coalesced their updates.
Related but distinct from #6613 (inline object props, fixed in 3.5.0) and #7463 (React 19 Suspense ref cleanup, open) — this one needs no Suspense and survives full prop identity stabilization. Happy to put together a minimal repro if useful.
Versions: recharts 3.9.2, React 19.2.5, Next.js 16.2.10 (Turbopack), Chrome.
Setup: an
AreaChart/LineChartinsideResponsiveContainerwithXAxis,YAxis,Tooltip,CartesianGrid, and a fewReferenceLines. The parent component re-renders in response to a range slider (an "as of" time scrubber): each input event callssetState, which recomputes the chart'sdataarray and aReferenceLinex.Problem 1 — hard crash under fast scrubbing. With the app calling
setStateonce per slider input event (no throttling), a fast mouse drag (input events arrive faster than frame rate) trips React's nested update limit:Captured stack:
RenderedTicksReporter.useEffect→ storedispatch→notifyNestedSubs→forceStoreRerender, firing duringcommitPassiveUnmountOnFiber, interleaved with the app's owndispatchSetStateper slider event until the 50 nested update limit throws. In development this crashes the route to the nearest error boundary at genuine human drag speed; in a production build the same crash (minified React #185) reproduces under higher-rate event bursts.Problem 2 — the dev warning floor. After fixing the app side — coalescing slider updates to one
setStateper animation frame, hoisting every static prop to module constants (margin,axisLine,tickFormatter,labelobjects), and memoizing theReferenceLineelements so only genuinely data-driven props change identity — the crash is gone at any input rate. But during continuous scrubbing the dev-only "Maximum update depth exceeded"console.errorstill fires roughly once per 50 frames: each frame's legitimate data change (newdataarray +ReferenceLinex) is followed by at least one nested store dispatch from a recharts passive effect, so React's nested update counter never sees a quiet frame to reset.Question/ask: could the axis/tick settings sync (and
RenderedTicksReporter) skip dispatching when the incoming settings are value-equal to the stored ones, rather than reference-equal? That would let data-driven re-renders (animation/scrubbing use cases) complete without a nested store dispatch per frame, which both removes the dev warning floor and adds headroom against the hard crash for apps that haven't frame-coalesced their updates.Related but distinct from #6613 (inline object props, fixed in 3.5.0) and #7463 (React 19 Suspense ref cleanup, open) — this one needs no Suspense and survives full prop identity stabilization. Happy to put together a minimal repro if useful.