@@ -120,6 +120,8 @@ const AdvancedChart = forwardRef<AdvancedChartRef, AdvancedChartProps>(
120120 const prevChartTypeRef = useRef ( chartType ) ;
121121 const prevOhlcvDataRef = useRef < OHLCVBar [ ] > ( [ ] ) ;
122122 const prevOhlcvSeriesKeyRef = useRef < string | undefined > ( undefined ) ;
123+ /** When non-null, `ohlcvData` is still the previous series' array; skip sync until the hook replaces it. */
124+ const ohlcvSeriesStaleSnapshotRef = useRef < OHLCVBar [ ] | null > ( null ) ;
123125 const tradingViewOpenInterceptRef = useRef ( 0 ) ;
124126
125127 const htmlContent = useMemo (
@@ -141,6 +143,7 @@ const AdvancedChart = forwardRef<AdvancedChartRef, AdvancedChartProps>(
141143 prevChartTypeRef . current = undefined ;
142144 prevOhlcvDataRef . current = [ ] ;
143145 prevOhlcvSeriesKeyRef . current = undefined ;
146+ ohlcvSeriesStaleSnapshotRef . current = null ;
144147 } , [ htmlContent ] ) ; // eslint-disable-line react-hooks/exhaustive-deps
145148
146149 // ---- Helpers ----
@@ -171,6 +174,19 @@ const AdvancedChart = forwardRef<AdvancedChartRef, AdvancedChartProps>(
171174 } , LAYOUT_SETTLE_FALLBACK_MS ) ;
172175 } , [ isChartReady , clearLayoutSettleTimeout ] ) ;
173176
177+ // WebView remounts when `key` changes; parent state would otherwise still look "ready".
178+ // `CHART_READY` clears indicator/position/chart-type refs once the new instance loads.
179+ useEffect ( ( ) => {
180+ if ( ohlcvSeriesKey === undefined ) {
181+ return ;
182+ }
183+ setChartReadyCount ( 0 ) ;
184+ setWebViewLoaded ( false ) ;
185+ setLayoutSettling ( false ) ;
186+ clearLayoutSettleTimeout ( ) ;
187+ ohlcvSeriesStaleSnapshotRef . current = null ;
188+ } , [ ohlcvSeriesKey , clearLayoutSettleTimeout ] ) ;
189+
174190 useEffect (
175191 ( ) => ( ) => {
176192 clearLayoutSettleTimeout ( ) ;
@@ -397,19 +413,23 @@ const AdvancedChart = forwardRef<AdvancedChartRef, AdvancedChartProps>(
397413 useEffect ( ( ) => {
398414 if ( ohlcvData . length === 0 || ! webViewLoaded ) return ;
399415
416+ if ( ohlcvSeriesStaleSnapshotRef . current !== null ) {
417+ if ( ohlcvData !== ohlcvSeriesStaleSnapshotRef . current ) {
418+ ohlcvSeriesStaleSnapshotRef . current = null ;
419+ } else {
420+ return ;
421+ }
422+ }
423+
400424 const prevData = prevOhlcvDataRef . current ;
401425
402426 if (
403427 ohlcvSeriesKey !== undefined &&
404428 ohlcvSeriesKey !== prevOhlcvSeriesKeyRef . current
405429 ) {
406430 if ( prevOhlcvSeriesKeyRef . current !== undefined ) {
407- // Time range switch: ohlcvData is still stale from the previous
408- // period (fetch is in progress). Show skeleton, mark the key, and
409- // clear prevData so the fresh data triggers the length-diff branch
410- // on arrival — avoiding sending stale data to the WebView which
411- // causes a resolution race condition in TradingView.
412431 beginFullOhlcvLayoutSettle ( ) ;
432+ ohlcvSeriesStaleSnapshotRef . current = ohlcvData ;
413433 prevOhlcvSeriesKeyRef . current = ohlcvSeriesKey ;
414434 prevOhlcvDataRef . current = [ ] ;
415435 return ;
@@ -561,6 +581,7 @@ const AdvancedChart = forwardRef<AdvancedChartRef, AdvancedChartProps>(
561581 < View style = { styles . container } >
562582 < View style = { styles . chartSurface } >
563583 < WebView
584+ key = { `advanced-chart-${ ohlcvSeriesKey ?? '' } ` }
564585 ref = { webViewRef }
565586 source = { { html : htmlContent , baseUrl : CHARTING_LIBRARY_BASE_URL } }
566587 style = { styles . webview }
0 commit comments