From 5932df4bbff199247545920bbce9f33baf10debf Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Mon, 12 Jan 2026 12:02:04 -0500 Subject: [PATCH 1/6] fixes issue where components wouldnt remount when passed as a children prop (cherry picked from commit cdd40ed1f23eaea4d84f717a206f3cfc1ab2f8fd) --- dash/dash-renderer/src/wrapper/DashWrapper.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dash/dash-renderer/src/wrapper/DashWrapper.tsx b/dash/dash-renderer/src/wrapper/DashWrapper.tsx index 57e152ebcc..40f5817f36 100644 --- a/dash/dash-renderer/src/wrapper/DashWrapper.tsx +++ b/dash/dash-renderer/src/wrapper/DashWrapper.tsx @@ -65,6 +65,7 @@ function DashWrapper({ const dispatch = useDispatch(); const memoizedKeys: MutableRefObject = useRef({}); const newRender = useRef(false); + const freshRenders = useRef(0); const renderedPath = useRef(componentPath); let renderComponent: any = null; let renderComponentProps: any = null; @@ -85,6 +86,7 @@ function DashWrapper({ if (_newRender) { newRender.current = true; renderH = 0; + freshRenders.current += 1; if (renderH in memoizedKeys.current) { delete memoizedKeys.current[renderH]; } @@ -498,6 +500,7 @@ function DashWrapper({ } error={_dashprivate_error} dispatch={dispatch} + key={freshRenders.current} > {React.isValidElement(hydrated) ? hydrated :
} From cb1f299b7909774eded40e1871f3aa1950ca7faf Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Tue, 20 Jan 2026 18:13:46 -0500 Subject: [PATCH 2/6] update to remove hashes of decendents upon `newRender` --- dash/dash-renderer/src/actions/constants.js | 3 ++- dash/dash-renderer/src/actions/index.js | 1 + dash/dash-renderer/src/reducers/reducer.js | 11 +++++++++++ dash/dash-renderer/src/wrapper/DashWrapper.tsx | 6 +++++- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/dash/dash-renderer/src/actions/constants.js b/dash/dash-renderer/src/actions/constants.js index 9c744f1655..47406b6627 100644 --- a/dash/dash-renderer/src/actions/constants.js +++ b/dash/dash-renderer/src/actions/constants.js @@ -10,7 +10,8 @@ const actionList = { ON_ERROR: 1, SET_HOOKS: 1, INSERT_COMPONENT: 1, - REMOVE_COMPONENT: 1 + REMOVE_COMPONENT: 1, + RESET_COMPONENT_STATE: 1 }; export const getAction = action => { diff --git a/dash/dash-renderer/src/actions/index.js b/dash/dash-renderer/src/actions/index.js index 5df75d708e..ee7f8fd9db 100644 --- a/dash/dash-renderer/src/actions/index.js +++ b/dash/dash-renderer/src/actions/index.js @@ -22,6 +22,7 @@ export const insertComponent = createAction(getAction('INSERT_COMPONENT')); export const removeComponent = createAction(getAction('REMOVE_COMPONENT')); export const onPropChange = createAction(getAction('ON_PROP_CHANGE')); +export const resetComponentState = createAction(getAction('RESET_COMPONENT_STATE')); export function updateProps(payload) { return (dispatch, getState) => { diff --git a/dash/dash-renderer/src/reducers/reducer.js b/dash/dash-renderer/src/reducers/reducer.js index 56d2c82ad2..b9704c96b7 100644 --- a/dash/dash-renderer/src/reducers/reducer.js +++ b/dash/dash-renderer/src/reducers/reducer.js @@ -49,6 +49,17 @@ const layoutHashes = (state = {}, action) => { }, state ); + } else if (action.type === 'RESET_COMPONENT_STATE') { + const { itempath } = action.payload; + if (itempath) { + const prefixStr = stringifyPath(itempath); + // Remove all hashes for keys starting with prefixStr + return Object.fromEntries( + Object.entries(state).filter( + ([key]) => !key.startsWith(prefixStr) + ) + ); + }; } return state; }; diff --git a/dash/dash-renderer/src/wrapper/DashWrapper.tsx b/dash/dash-renderer/src/wrapper/DashWrapper.tsx index 40f5817f36..43fccdb2c3 100644 --- a/dash/dash-renderer/src/wrapper/DashWrapper.tsx +++ b/dash/dash-renderer/src/wrapper/DashWrapper.tsx @@ -21,7 +21,7 @@ import {useSelector, useDispatch, batch} from 'react-redux'; import ComponentErrorBoundary from '../components/error/ComponentErrorBoundary.react'; import {DashLayoutPath, UpdatePropsPayload} from '../types/component'; import {DashConfig} from '../config'; -import {notifyObservers, onError, updateProps} from '../actions'; +import {notifyObservers, onError, updateProps, resetComponentState} from '../actions'; import {getWatchedKeys, stringifyId} from '../actions/dependencies'; import { createElement, @@ -90,6 +90,10 @@ function DashWrapper({ if (renderH in memoizedKeys.current) { delete memoizedKeys.current[renderH]; } + // Reset hashes and layout for this component and all descendants + dispatch(resetComponentState({ + itempath: componentPath, + })); } else { newRender.current = false; } From 8e960df105276a5cc657c0eb9a66ab8486258105 Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Tue, 20 Jan 2026 20:46:44 -0500 Subject: [PATCH 3/6] fix for lint --- dash/dash-renderer/src/actions/index.js | 4 +++- dash/dash-renderer/src/wrapper/DashWrapper.tsx | 15 +++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/dash/dash-renderer/src/actions/index.js b/dash/dash-renderer/src/actions/index.js index ee7f8fd9db..7c92d17afc 100644 --- a/dash/dash-renderer/src/actions/index.js +++ b/dash/dash-renderer/src/actions/index.js @@ -22,7 +22,9 @@ export const insertComponent = createAction(getAction('INSERT_COMPONENT')); export const removeComponent = createAction(getAction('REMOVE_COMPONENT')); export const onPropChange = createAction(getAction('ON_PROP_CHANGE')); -export const resetComponentState = createAction(getAction('RESET_COMPONENT_STATE')); +export const resetComponentState = createAction( + getAction('RESET_COMPONENT_STATE') +); export function updateProps(payload) { return (dispatch, getState) => { diff --git a/dash/dash-renderer/src/wrapper/DashWrapper.tsx b/dash/dash-renderer/src/wrapper/DashWrapper.tsx index 43fccdb2c3..80f973ba91 100644 --- a/dash/dash-renderer/src/wrapper/DashWrapper.tsx +++ b/dash/dash-renderer/src/wrapper/DashWrapper.tsx @@ -21,7 +21,12 @@ import {useSelector, useDispatch, batch} from 'react-redux'; import ComponentErrorBoundary from '../components/error/ComponentErrorBoundary.react'; import {DashLayoutPath, UpdatePropsPayload} from '../types/component'; import {DashConfig} from '../config'; -import {notifyObservers, onError, updateProps, resetComponentState} from '../actions'; +import { + notifyObservers, + onError, + updateProps, + resetComponentState +} from '../actions'; import {getWatchedKeys, stringifyId} from '../actions/dependencies'; import { createElement, @@ -91,9 +96,11 @@ function DashWrapper({ delete memoizedKeys.current[renderH]; } // Reset hashes and layout for this component and all descendants - dispatch(resetComponentState({ - itempath: componentPath, - })); + dispatch( + resetComponentState({ + itempath: componentPath + }) + ); } else { newRender.current = false; } From fd25ea8484eb8c4ec8587b864fea9a472caa5053 Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Tue, 20 Jan 2026 21:04:15 -0500 Subject: [PATCH 4/6] fixing issue with bad setState --- .../dash-renderer/src/wrapper/DashWrapper.tsx | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/dash/dash-renderer/src/wrapper/DashWrapper.tsx b/dash/dash-renderer/src/wrapper/DashWrapper.tsx index 80f973ba91..8a017ed09d 100644 --- a/dash/dash-renderer/src/wrapper/DashWrapper.tsx +++ b/dash/dash-renderer/src/wrapper/DashWrapper.tsx @@ -1,4 +1,10 @@ -import React, {useCallback, MutableRefObject, useRef, useMemo} from 'react'; +import React, { + useCallback, + MutableRefObject, + useRef, + useMemo, + useEffect +} from 'react'; import { path, concat, @@ -95,12 +101,6 @@ function DashWrapper({ if (renderH in memoizedKeys.current) { delete memoizedKeys.current[renderH]; } - // Reset hashes and layout for this component and all descendants - dispatch( - resetComponentState({ - itempath: componentPath - }) - ); } else { newRender.current = false; } @@ -445,6 +445,16 @@ function DashWrapper({ return props; }; + useEffect(() => { + if (_newRender) { + dispatch( + resetComponentState({ + itempath: componentPath + }) + ); + } + }, [_newRender]); + const hydrateFunc = () => { if (newRender.current) { renderComponent = _passedComponent; From dc2e3ad2693426326d8f58f7f0442502b3db4eb6 Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Tue, 20 Jan 2026 21:04:47 -0500 Subject: [PATCH 5/6] fixing for lint --- dash/dash-renderer/src/reducers/reducer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dash/dash-renderer/src/reducers/reducer.js b/dash/dash-renderer/src/reducers/reducer.js index b9704c96b7..5952bab271 100644 --- a/dash/dash-renderer/src/reducers/reducer.js +++ b/dash/dash-renderer/src/reducers/reducer.js @@ -50,7 +50,7 @@ const layoutHashes = (state = {}, action) => { state ); } else if (action.type === 'RESET_COMPONENT_STATE') { - const { itempath } = action.payload; + const {itempath} = action.payload; if (itempath) { const prefixStr = stringifyPath(itempath); // Remove all hashes for keys starting with prefixStr From 316b9ac9b303cca21eb46200a910e21391783346 Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Tue, 20 Jan 2026 21:28:30 -0500 Subject: [PATCH 6/6] fix for lint --- dash/dash-renderer/src/reducers/reducer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dash/dash-renderer/src/reducers/reducer.js b/dash/dash-renderer/src/reducers/reducer.js index 5952bab271..759c198989 100644 --- a/dash/dash-renderer/src/reducers/reducer.js +++ b/dash/dash-renderer/src/reducers/reducer.js @@ -59,7 +59,7 @@ const layoutHashes = (state = {}, action) => { ([key]) => !key.startsWith(prefixStr) ) ); - }; + } } return state; };