Skip to content

Commit 31f6d52

Browse files
authored
Undo memoizing all of props options and only memoize Objects/Arrays (#189)
* Undo memoizing all of prop options * Only memoize objects/arrays from props
1 parent e4f98b2 commit 31f6d52

File tree

3 files changed

+91
-49
lines changed

3 files changed

+91
-49
lines changed

src/hooks/useCioAutocomplete.ts

Lines changed: 6 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import { useMemo, useState } from 'react';
44
import useCioClient from './useCioClient';
55
import useDownShift from './useDownShift';
66
import {
7-
CioAutocompleteProps,
87
CioClientConfig,
98
Section,
109
UserDefinedSection,
1110
HTMLPropsWithCioDataAttributes,
1211
Item,
12+
UseCioAutocompleteOptions,
1313
} from '../types';
1414
import usePrevious from './usePrevious';
1515
import {
@@ -23,7 +23,8 @@ import {
2323
import useConsoleErrors from './useConsoleErrors';
2424
import useSections from './useSections';
2525
import useRecommendationsObserver from './useRecommendationsObserver';
26-
import { isAutocompleteSection, isCustomSection, isRecommendationsSection } from '../typeGuards';
26+
import { isCustomSection, isRecommendationsSection } from '../typeGuards';
27+
import useNormalizedProps from './useNormalizedProps';
2728

2829
export const defaultSections: UserDefinedSection[] = [
2930
{
@@ -36,65 +37,21 @@ export const defaultSections: UserDefinedSection[] = [
3637
},
3738
];
3839

39-
export type UseCioAutocompleteOptions = Omit<CioAutocompleteProps, 'children'>;
40-
41-
const convertLegacyParametersAndAddDefaults = (sections: UserDefinedSection[]) =>
42-
sections.map((config) => {
43-
if (isRecommendationsSection(config)) {
44-
if (config.identifier && !config.podId) {
45-
return { ...config, podId: config.identifier };
46-
}
47-
48-
if (!config.indexSectionName) {
49-
return { ...config, indexSectionName: 'Products' };
50-
}
51-
}
52-
53-
if (isAutocompleteSection(config)) {
54-
if (config.identifier && !config.indexSectionName) {
55-
return { ...config, indexSectionName: config.identifier };
56-
}
57-
}
58-
59-
return config;
60-
});
61-
6240
const useCioAutocomplete = (options: UseCioAutocompleteOptions) => {
63-
// eslint-disable-next-line react-hooks/exhaustive-deps
64-
const memoizedOptions = useMemo(() => options, [JSON.stringify(options)]);
65-
41+
const { sections, zeroStateSections, cioJsClientOptions, advancedParameters } =
42+
useNormalizedProps(options);
6643
const {
6744
onSubmit,
6845
onChange,
6946
openOnFocus,
7047
apiKey,
7148
cioJsClient,
72-
cioJsClientOptions,
7349
placeholder = 'What can we help you find today?',
7450
autocompleteClassName = 'cio-autocomplete',
75-
advancedParameters,
7651
defaultInput,
7752
getSearchResultsUrl,
7853
...rest
79-
} = memoizedOptions;
80-
81-
let { sections = defaultSections, zeroStateSections } = memoizedOptions;
82-
83-
sections = useMemo(() => {
84-
if (sections) {
85-
return convertLegacyParametersAndAddDefaults(sections);
86-
}
87-
88-
return sections;
89-
}, [sections]);
90-
91-
zeroStateSections = useMemo(() => {
92-
if (zeroStateSections) {
93-
return convertLegacyParametersAndAddDefaults(zeroStateSections);
94-
}
95-
96-
return zeroStateSections;
97-
}, [zeroStateSections]);
54+
} = options;
9855

9956
const [query, setQuery] = useState(defaultInput || '');
10057
const previousQuery = usePrevious(query);

src/hooks/useNormalizedProps.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/* eslint-disable react-hooks/exhaustive-deps */
2+
import { useMemo } from 'react';
3+
import { UseCioAutocompleteOptions, UserDefinedSection } from '../types';
4+
import { isAutocompleteSection, isRecommendationsSection } from '../typeGuards';
5+
6+
export const defaultSections: UserDefinedSection[] = [
7+
{
8+
indexSectionName: 'Search Suggestions',
9+
type: 'autocomplete',
10+
},
11+
{
12+
indexSectionName: 'Products',
13+
type: 'autocomplete',
14+
},
15+
];
16+
17+
const convertLegacyParametersAndAddDefaults = (sections: UserDefinedSection[]) =>
18+
sections.map((config) => {
19+
if (isRecommendationsSection(config)) {
20+
if (config.identifier && !config.podId) {
21+
return { ...config, podId: config.identifier };
22+
}
23+
24+
if (!config.indexSectionName) {
25+
return { ...config, indexSectionName: 'Products' };
26+
}
27+
}
28+
29+
if (isAutocompleteSection(config)) {
30+
if (config.identifier && !config.indexSectionName) {
31+
return { ...config, indexSectionName: config.identifier };
32+
}
33+
}
34+
35+
return config;
36+
});
37+
38+
const normalizeSections = (sections: UserDefinedSection[] | undefined) => {
39+
if (sections) {
40+
return convertLegacyParametersAndAddDefaults(sections);
41+
}
42+
43+
return sections;
44+
};
45+
46+
// Normalize and Memoize Objects to prevent infinite rerenders if users pass object literals to useCioAutocomplete
47+
const useNormalizedProps = (options: UseCioAutocompleteOptions) => {
48+
const {
49+
sections = defaultSections,
50+
zeroStateSections,
51+
cioJsClientOptions,
52+
advancedParameters,
53+
} = options;
54+
55+
const sectionsMemoized = useMemo(
56+
() => normalizeSections(sections),
57+
[JSON.stringify(sections)]
58+
) as UserDefinedSection[];
59+
60+
const zeroStateSectionsMemoized = useMemo(
61+
() => normalizeSections(zeroStateSections),
62+
[JSON.stringify(zeroStateSections)]
63+
);
64+
65+
const cioJsClientOptionsMemoized = useMemo(
66+
() => cioJsClientOptions,
67+
[JSON.stringify(cioJsClientOptions)]
68+
);
69+
70+
const advancedParametersMemoized = useMemo(
71+
() => advancedParameters,
72+
[JSON.stringify(advancedParameters)]
73+
);
74+
75+
return {
76+
sections: sectionsMemoized,
77+
zeroStateSections: zeroStateSectionsMemoized,
78+
cioJsClientOptions: cioJsClientOptionsMemoized,
79+
advancedParameters: advancedParametersMemoized,
80+
};
81+
};
82+
83+
export default useNormalizedProps;

src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ type OptionalItemsComboboxProps<Item> = Partial<UseComboboxProps<Item>> & {
3939
items?: Item[];
4040
};
4141

42+
export type UseCioAutocompleteOptions = Omit<CioAutocompleteProps, 'children'>;
43+
4244
export type CioAutocompleteProps = CioClientConfig &
4345
OptionalItemsComboboxProps<Item> & {
4446
openOnFocus?: boolean;

0 commit comments

Comments
 (0)