From 80916cd5548d55f32401daaccf2653e3acab54d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Rialland?= Date: Wed, 30 Nov 2022 20:16:15 +0100 Subject: [PATCH] Optimize search params simulation with reselect --- site/package.json | 1 + .../utils/useSearchParamsSimulationSharing.ts | 26 +++---------------- site/source/selectors/simulationSelectors.ts | 19 +++++++------- yarn.lock | 8 ++++++ 4 files changed, 23 insertions(+), 31 deletions(-) diff --git a/site/package.json b/site/package.json index 68a06fc5c..622841c99 100644 --- a/site/package.json +++ b/site/package.json @@ -97,6 +97,7 @@ "recharts": "2.1.16", "reduce-reducers": "^1.0.4", "redux": "^4.2.0", + "reselect": "^4.1.7", "styled-components": "^5.3.6", "whatwg-fetch": "^3.6.2" }, diff --git a/site/source/components/utils/useSearchParamsSimulationSharing.ts b/site/source/components/utils/useSearchParamsSimulationSharing.ts index b7e50ab97..163106d40 100644 --- a/site/source/components/utils/useSearchParamsSimulationSharing.ts +++ b/site/source/components/utils/useSearchParamsSimulationSharing.ts @@ -2,11 +2,11 @@ import { DottedName } from 'modele-social' import Engine, { ParsedRules, serializeEvaluation } from 'publicodes' import { useEffect, useMemo, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' -import { useLocation, useSearchParams } from 'react-router-dom' +import { useSearchParams } from 'react-router-dom' import { batchUpdateSituation, setActiveTarget } from '@/actions/actions' import { useEngine } from '@/components/utils/EngineContext' -import { RootState, Situation } from '@/reducers/rootReducer' +import { Situation } from '@/reducers/rootReducer' import { configObjectifsSelector } from '@/selectors/simulationSelectors' type ShortName = string @@ -16,8 +16,6 @@ export default function useSearchParamsSimulationSharing() { const [urlSituationIsExtracted, setUrlSituationIsExtracted] = useState(false) const [searchParams, setSearchParams] = useSearchParams() const objectifs = useSelector(configObjectifsSelector) - const simulationUrl = useSelector((state: RootState) => state.simulation?.url) - const currentUrl = useLocation().pathname const dispatch = useDispatch() const engine = useEngine() @@ -27,14 +25,6 @@ export default function useSearchParamsSimulationSharing() { ) useEffect(() => { - // const hasConfig = Object.keys(config).length > 0 - - // // TODO: this check is specific to `useSimulationConfig` and - // // `setSimulationConfig`, so we'd prefer not doing it here. Other ideas - // // include having the config in a provider rather than in state. - // const configLoadedInState = simulationUrl === currentUrl - // if (!hasConfig || !configLoadedInState) return - // On load: if (!urlSituationIsExtracted) { const newSituation = getSituationFromSearchParams( @@ -61,16 +51,8 @@ export default function useSearchParamsSimulationSharing() { setUrlSituationIsExtracted(true) } - }, [ - currentUrl, - simulationUrl, - dispatch, - dottedNameParamName, - objectifs, - searchParams, - setSearchParams, - urlSituationIsExtracted, - ]) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) // Cleanup: useEffect(() => { diff --git a/site/source/selectors/simulationSelectors.ts b/site/source/selectors/simulationSelectors.ts index dcd6252ab..95e03a63e 100644 --- a/site/source/selectors/simulationSelectors.ts +++ b/site/source/selectors/simulationSelectors.ts @@ -1,6 +1,7 @@ import { DottedName } from 'modele-social' import Engine, { utils } from 'publicodes' import { useSelector } from 'react-redux' +import { createSelector } from 'reselect' import { useEngine } from '@/components/utils/EngineContext' import { RootState, Situation } from '@/reducers/rootReducer' @@ -8,16 +9,16 @@ import { RootState, Situation } from '@/reducers/rootReducer' export const configSelector = (state: RootState) => state.simulation?.config ?? {} -export const configObjectifsSelector = (state: RootState) => { - const config = configSelector(state) - - const objectifs = [ - ...(config['objectifs exclusifs'] ?? []), - ...(config.objectifs ?? []), +export const configObjectifsSelector = createSelector( + [ + (state: RootState) => configSelector(state)['objectifs exclusifs'], + (state: RootState) => configSelector(state).objectifs, + ], + (objectifsExclusifs, objectifs) => [ + ...(objectifsExclusifs ?? []), + ...(objectifs ?? []), ] - - return objectifs -} +) const emptySituation: Situation = {} diff --git a/yarn.lock b/yarn.lock index 8243a87d7..16fdf7298 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25011,6 +25011,13 @@ __metadata: languageName: node linkType: hard +"reselect@npm:^4.1.7": + version: 4.1.7 + resolution: "reselect@npm:4.1.7" + checksum: 738d8e2b8f0dca154ad29de6a209c9fbca2d70ae6788fd85df87f2c74b95a65bbf2d16d43a9e2faff39de34d17a29d706ba08a6b2ee5660c09589edbd19af7e1 + languageName: node + linkType: hard + "resolve-alpn@npm:^1.2.0": version: 1.2.1 resolution: "resolve-alpn@npm:1.2.1" @@ -25963,6 +25970,7 @@ __metadata: recharts: 2.1.16 reduce-reducers: ^1.0.4 redux: ^4.2.0 + reselect: ^4.1.7 rimraf: ^3.0.2 rollup-plugin-toml: ^1.0.0 serve-static: ^1.15.0