diff --git a/frontend/src/framework/EnsembleSet.ts b/frontend/src/framework/EnsembleSet.ts index 604eb3acc..4c75a86e9 100644 --- a/frontend/src/framework/EnsembleSet.ts +++ b/frontend/src/framework/EnsembleSet.ts @@ -7,10 +7,14 @@ import { isEnsembleIdentOfType } from "./utils/ensembleIdentUtils"; export class EnsembleSet { private _regularEnsembleArray: RegularEnsemble[]; private _deltaEnsembleArray: DeltaEnsemble[]; + private _allEnsemblesArray: (RegularEnsemble | DeltaEnsemble)[]; constructor(ensembles: RegularEnsemble[], deltaEnsembles: DeltaEnsemble[] = []) { this._regularEnsembleArray = ensembles; this._deltaEnsembleArray = deltaEnsembles; + + // Precomputed for reference stability across renders + this._allEnsemblesArray = [...ensembles, ...deltaEnsembles]; } /** @@ -58,7 +62,7 @@ export class EnsembleSet { * @returns An array of all ensembles in the set. */ getEnsembleArray(): readonly (RegularEnsemble | DeltaEnsemble)[] { - return [...this._regularEnsembleArray, ...this._deltaEnsembleArray]; + return this._allEnsemblesArray; } /** diff --git a/frontend/src/framework/components/EnsembleDropdown/ensembleDropdown.tsx b/frontend/src/framework/components/EnsembleDropdown/ensembleDropdown.tsx index b56b38090..28a5b8636 100644 --- a/frontend/src/framework/components/EnsembleDropdown/ensembleDropdown.tsx +++ b/frontend/src/framework/components/EnsembleDropdown/ensembleDropdown.tsx @@ -30,6 +30,20 @@ export type EnsembleDropdownProps = ( export function EnsembleDropdown(props: EnsembleDropdownProps): JSX.Element { const { onChange, ensembles, allowDeltaEnsembles, value, ensembleRealizationFilterFunction, ...rest } = props; + const optionsArray = React.useMemo(() => { + return ensembles.map((ens) => ({ + value: ens.getIdent().toString(), + label: ens.getDisplayName(), + adornment: ( + + ), + })); + }, [ensembles, ensembleRealizationFilterFunction]); + const handleSelectionChange = React.useCallback( function handleSelectionChange(selectedEnsembleIdentStr: string) { const foundEnsemble = ensembles.find( @@ -52,20 +66,5 @@ export function EnsembleDropdown(props: EnsembleDropdownProps): JSX.Element { [allowDeltaEnsembles, ensembles, onChange], ); - const optionsArray: DropdownOption[] = []; - for (const ens of ensembles) { - optionsArray.push({ - value: ens.getIdent().toString(), - label: ens.getDisplayName(), - adornment: ( - - ), - }); - } - return ; } diff --git a/frontend/src/framework/components/EnsemblePicker/ensemblePicker.tsx b/frontend/src/framework/components/EnsemblePicker/ensemblePicker.tsx index 7acdc2e6b..eea6d0f43 100644 --- a/frontend/src/framework/components/EnsemblePicker/ensemblePicker.tsx +++ b/frontend/src/framework/components/EnsemblePicker/ensemblePicker.tsx @@ -31,18 +31,16 @@ export type EnsemblePickerProps = ( export function EnsemblePicker(props: EnsemblePickerProps): JSX.Element { const { onChange, ensembles, value, allowDeltaEnsembles, ensembleRealizationFilterFunction } = props; - const optionsArray: TagOption[] = []; - for (const ens of ensembles) { - optionsArray.push({ + const selectedArray = React.useMemo(() => { + return value.map((ident) => ident.toString()); + }, [value]); + + const optionsArray = React.useMemo(() => { + return ensembles.map((ens) => ({ value: ens.getIdent().toString(), label: ens.getDisplayName(), - }); - } - - const selectedArray: string[] = []; - for (const ident of value) { - selectedArray.push(ident.toString()); - } + })); + }, [ensembles]); const handleSelectionChange = React.useCallback( function handleSelectionChanged(selectedEnsembleIdentStringArray: string[]) { diff --git a/frontend/src/framework/components/EnsembleSelect/ensembleSelect.tsx b/frontend/src/framework/components/EnsembleSelect/ensembleSelect.tsx index 1079f4223..f0cccc6f4 100644 --- a/frontend/src/framework/components/EnsembleSelect/ensembleSelect.tsx +++ b/frontend/src/framework/components/EnsembleSelect/ensembleSelect.tsx @@ -35,6 +35,24 @@ export function EnsembleSelect(props: EnsembleSelectProps): JSX.Element { const { onChange, ensembles, value, allowDeltaEnsembles, multiple, ensembleRealizationFilterFunction, ...rest } = props; + const selectedArray = React.useMemo(() => { + return value.map((ident) => ident.toString()); + }, [value]); + + const optionsArray = React.useMemo(() => { + return ensembles.map((ens) => ({ + value: ens.getIdent().toString(), + label: ens.getDisplayName(), + adornment: ( + + ), + })); + }, [ensembles, ensembleRealizationFilterFunction]); + const handleSelectionChange = React.useCallback( function handleSelectionChanged(selectedEnsembleIdentStringArray: string[]) { const identArray: (RegularEnsembleIdent | DeltaEnsembleIdent)[] = []; @@ -62,35 +80,13 @@ export function EnsembleSelect(props: EnsembleSelectProps): JSX.Element { [allowDeltaEnsembles, ensembles, onChange], ); - const optionsArray: SelectOption[] = []; - for (const ens of ensembles) { - optionsArray.push({ - value: ens.getIdent().toString(), - label: ens.getDisplayName(), - adornment: ( - - ), - }); - } - - const selectedArray: string[] = []; - for (const ident of value) { - selectedArray.push(ident.toString()); - } - - const isMultiple = multiple ?? true; - return (