From 86f01eb002c6cb8578a86707ef75da7e3fc99757 Mon Sep 17 00:00:00 2001 From: Brandon Presley Date: Sun, 1 Jan 2023 13:39:10 +1300 Subject: [PATCH] Memoize the most expensive parts of SettingsPage --- SettingsPage.tsx | 212 +++++++++++++++++++++++++---------------------- 1 file changed, 114 insertions(+), 98 deletions(-) diff --git a/SettingsPage.tsx b/SettingsPage.tsx index 7b5ea51..d46e116 100644 --- a/SettingsPage.tsx +++ b/SettingsPage.tsx @@ -30,7 +30,6 @@ export default function SettingsPage() { const [formatOptions, setFormatOptions] = useState(twelveHours) const [importing, setImporting] = useState(false) const {reset} = useNavigation>() - const today = new Date() const {watch, setValue} = useForm({ defaultValues: () => settingsRepo.findOne({where: {}}), @@ -80,32 +79,9 @@ export default function SettingsPage() { [settings], ) - const changeString = useCallback( - async (key: keyof Settings, value: string) => { - setValue(key, value) - await settingsRepo.save({...settings, [key]: value}) - switch (key) { - case 'date': - return toast('Changed date format') - case 'darkColor': - setDarkColor(value) - return toast('Set primary color for dark mode.') - case 'lightColor': - setLightColor(value) - return toast('Set primary color for light mode.') - case 'vibrate': - return toast('Set primary color for light mode.') - case 'sound': - return toast('Sound will play after rest timers.') - case 'theme': - setTheme(value as string) - if (value === 'dark') toast('Theme will always be dark.') - else if (value === 'light') toast('Theme will always be light.') - else if (value === 'system') toast('Theme will follow system.') - return - } - }, - [settings, setTheme, setDarkColor, setLightColor, setValue], + const filter = useCallback( + ({name}) => name.toLowerCase().includes(term.toLowerCase()), + [term], ) const changeBoolean = useCallback( @@ -163,30 +139,66 @@ export default function SettingsPage() { [changeBoolean], ) - const selects: Input[] = [ - {name: 'Theme', value: theme, items: themeOptions, key: 'theme'}, - { - name: 'Dark color', - value: darkColor, - items: lightOptions, - key: 'darkColor', + const switchesMarkup = useMemo( + () => switches.filter(filter).map(s => renderSwitch(s)), + [filter, switches, renderSwitch], + ) + + const changeString = useCallback( + async (key: keyof Settings, value: string) => { + setValue(key, value) + await settingsRepo.save({...settings, [key]: value}) + switch (key) { + case 'date': + return toast('Changed date format') + case 'darkColor': + setDarkColor(value) + return toast('Set primary color for dark mode.') + case 'lightColor': + setLightColor(value) + return toast('Set primary color for light mode.') + case 'vibrate': + return toast('Set primary color for light mode.') + case 'sound': + return toast('Sound will play after rest timers.') + case 'theme': + setTheme(value as string) + if (value === 'dark') toast('Theme will always be dark.') + else if (value === 'light') toast('Theme will always be light.') + else if (value === 'system') toast('Theme will follow system.') + return + } }, - { - name: 'Light color', - value: lightColor, - items: darkOptions, - key: 'lightColor', - }, - { - name: 'Date format', - value: settings.date, - items: formatOptions.map(option => ({ - label: format(today, option), - value: option, - })), - key: 'date', - }, - ] + [settings, setTheme, setDarkColor, setLightColor, setValue], + ) + + const selects: Input[] = useMemo(() => { + const today = new Date() + return [ + {name: 'Theme', value: theme, items: themeOptions, key: 'theme'}, + { + name: 'Dark color', + value: darkColor, + items: lightOptions, + key: 'darkColor', + }, + { + name: 'Light color', + value: lightColor, + items: darkOptions, + key: 'lightColor', + }, + { + name: 'Date format', + value: settings.date, + items: formatOptions.map(option => ({ + label: format(today, option), + value: option, + })), + key: 'date', + }, + ] + }, [settings.date, darkColor, formatOptions, theme, lightColor]) const renderSelect = useCallback( (item: Input) => ( @@ -201,6 +213,11 @@ export default function SettingsPage() { [changeString], ) + const selectsMarkup = useMemo( + () => selects.filter(filter).map(renderSelect), + [filter, selects, renderSelect], + ) + const confirmImport = useCallback(async () => { setImporting(false) await AppDataSource.destroy() @@ -222,53 +239,52 @@ export default function SettingsPage() { toast('Database exported. Check downloads.') }, []) - const filter = useCallback( - ({name}) => name.toLowerCase().includes(term.toLowerCase()), - [term], + const buttons = useMemo( + () => [ + { + name: 'Alarm sound', + element: ( + + Alarm sound + + + ), + }, + { + name: 'Export database', + element: ( + + ), + }, + { + name: 'Import database', + element: ( + + ), + }, + ], + [changeSound, exportDatabase, soundString], ) - const buttons = useMemo( - () => - [ - { - name: 'Alarm sound', - element: ( - - Alarm sound - - - ), - }, - { - name: 'Export database', - element: ( - - ), - }, - { - name: 'Import database', - element: ( - - ), - }, - ].filter(filter), - [changeSound, exportDatabase, soundString, filter], + const buttonsMarkup = useMemo( + () => buttons.filter(filter).map(b => b.element), + [buttons, filter], ) return ( @@ -277,9 +293,9 @@ export default function SettingsPage() { - {switches.filter(filter).map(s => renderSwitch(s))} - {selects.filter(filter).map(s => renderSelect(s))} - {buttons.map(b => b.element)} + {switchesMarkup} + {selectsMarkup} + {buttonsMarkup}