Skip to content

Commit ddbe210

Browse files
authored
Merge pull request #133 from Shopify/chore/perf-static-reference
Send a stable style object reference to wrapped components
2 parents b137e2f + 132e2f5 commit ddbe210

File tree

1 file changed

+36
-15
lines changed

1 file changed

+36
-15
lines changed

src/hooks/useRestyle.ts

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,25 @@ const filterRestyleProps = <
1515
omitPropertiesMap: Record<keyof TProps, boolean>,
1616
) => {
1717
return getKeys(props).reduce(
18-
({cleanProps, restyleProps}, key) => {
18+
({cleanProps, restyleProps, serializedRestyleProps}, key) => {
1919
if (omitPropertiesMap[key as keyof TProps]) {
20-
return {cleanProps, restyleProps: {...restyleProps, [key]: props[key]}};
20+
return {
21+
cleanProps,
22+
restyleProps: {...restyleProps, [key]: props[key]},
23+
serializedRestyleProps: `${serializedRestyleProps}${key}:${props[key]};`,
24+
};
2125
} else {
22-
return {cleanProps: {...cleanProps, [key]: props[key]}, restyleProps};
26+
return {
27+
cleanProps: {...cleanProps, [key]: props[key]},
28+
restyleProps,
29+
serializedRestyleProps,
30+
};
2331
}
2432
},
25-
{cleanProps: {}, restyleProps: {}} as {
33+
{cleanProps: {}, restyleProps: {}, serializedRestyleProps: ''} as {
2634
cleanProps: TProps;
2735
restyleProps: TRestyleProps;
36+
serializedRestyleProps: string;
2837
},
2938
);
3039
};
@@ -51,24 +60,36 @@ const useRestyle = <
5160
props: TProps,
5261
) => {
5362
const theme = useTheme<Theme>();
54-
5563
const dimensions = useDimensions();
5664

57-
const restyled = useMemo(() => {
58-
const {cleanProps, restyleProps} = filterRestyleProps(
59-
props,
60-
composedRestyleFunction.propertiesMap,
61-
);
62-
const style = composedRestyleFunction.buildStyle(restyleProps, {
65+
const {cleanProps, restyleProps, serializedRestyleProps} = filterRestyleProps(
66+
props,
67+
composedRestyleFunction.propertiesMap,
68+
);
69+
70+
const calculatedStyle = useMemo(() => {
71+
const style = composedRestyleFunction.buildStyle(restyleProps as TProps, {
6372
theme,
6473
dimensions,
6574
});
6675

67-
cleanProps.style = [style, props.style].filter(Boolean);
68-
return cleanProps;
69-
}, [composedRestyleFunction, props, dimensions, theme]);
76+
return [style, props.style].filter(Boolean);
77+
// We disable the exhaustive deps rule here in order to trigger the useMemo
78+
// when the serialized string of restyleProps changes instead of the object
79+
// reference which will change on every render.
80+
// eslint-disable-next-line react-hooks/exhaustive-deps
81+
}, [
82+
theme,
83+
dimensions,
84+
props.style,
85+
serializedRestyleProps,
86+
composedRestyleFunction,
87+
]);
7088

71-
return restyled;
89+
return {
90+
...cleanProps,
91+
style: calculatedStyle,
92+
};
7293
};
7394

7495
export default useRestyle;

0 commit comments

Comments
 (0)