From 3ef8a104c9fb3bb54a3b59a651a67e1ccb188561 Mon Sep 17 00:00:00 2001 From: Nick Grosenbacher Date: Tue, 17 Dec 2024 08:57:22 -0500 Subject: [PATCH] PORTALS-3364 - Fix QueryWrapper stale state bug - QueryWrapper component should always be reset via key when the initial query changes. See https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key --- .../CardContainerLogic/CardContainerLogic.tsx | 15 ++++++- .../QueryPerFacetPlotsCard.tsx | 15 ++++++- .../SingleQueryFacetPlotsCards.tsx | 11 ++++- .../QueryWrapperPlotNav.tsx | 21 +++++++--- .../StandaloneQueryWrapper.tsx | 42 ++++++++++++------- 5 files changed, 80 insertions(+), 24 deletions(-) diff --git a/packages/synapse-react-client/src/components/CardContainerLogic/CardContainerLogic.tsx b/packages/synapse-react-client/src/components/CardContainerLogic/CardContainerLogic.tsx index 3598953fb9..981fd62459 100644 --- a/packages/synapse-react-client/src/components/CardContainerLogic/CardContainerLogic.tsx +++ b/packages/synapse-react-client/src/components/CardContainerLogic/CardContainerLogic.tsx @@ -211,8 +211,21 @@ export function CardContainerLogic(props: CardContainerLogicProps) { SynapseConstants.BUNDLE_MASK_LAST_UPDATED_ON, } + /** + * Fully re-render the uncontrolled QueryWrapper component when the initial query changes. This eliminates a class of + * bugs where our 'derived' state (the current query), which should be reset, is out of sync with props. + * + * See https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key + */ + const queryWrapperKey = JSON.stringify(initQueryRequest) + return ( - + + + { setComponentKey(componentKey + 1) } + const { data: entity } = useGetEntity(entityId, versionNumber) const initQueryRequest: QueryBundleRequest = { entityId, @@ -326,11 +329,19 @@ function QueryWrapperPlotNav(props: QueryWrapperPlotNavProps) { const isFullTextSearchEnabled = (entity && isTable(entity) && entity.isSearchEnabled) ?? false + /** + * Fully re-render the uncontrolled QueryWrapper component when the initial query changes. This eliminates a class of + * bugs where our 'derived' state (the current query), which should be reset, is out of sync with props. + * + * See https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key + */ + const queryWrapperKey = `${JSON.stringify(initQueryRequest)}-${componentKey}` + return (