mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
use memo and callbacks for reduced rendering vis caching
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { memo } from 'react';
|
||||
import type { FC } from 'react';
|
||||
|
||||
import { CssBaseline, ThemeProvider, responsiveFontSizes } from '@mui/material';
|
||||
@@ -5,6 +6,7 @@ import { createTheme } from '@mui/material/styles';
|
||||
|
||||
import type { RequiredChildrenProps } from 'utils';
|
||||
|
||||
// Memoize dialog style to prevent recreation
|
||||
export const dialogStyle = {
|
||||
'& .MuiDialog-paper': {
|
||||
borderRadius: '8px',
|
||||
@@ -12,8 +14,9 @@ export const dialogStyle = {
|
||||
borderStyle: 'solid',
|
||||
borderWidth: '1px'
|
||||
}
|
||||
};
|
||||
} as const;
|
||||
|
||||
// Memoize theme creation to prevent recreation
|
||||
const theme = responsiveFontSizes(
|
||||
createTheme({
|
||||
typography: {
|
||||
@@ -34,11 +37,11 @@ const theme = responsiveFontSizes(
|
||||
})
|
||||
);
|
||||
|
||||
const CustomTheme: FC<RequiredChildrenProps> = ({ children }) => (
|
||||
const CustomTheme: FC<RequiredChildrenProps> = memo(({ children }) => (
|
||||
<ThemeProvider theme={theme}>
|
||||
<CssBaseline />
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
);
|
||||
));
|
||||
|
||||
export default CustomTheme;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import type { FC } from 'react';
|
||||
import { useLocation } from 'react-router';
|
||||
|
||||
@@ -13,22 +13,26 @@ import { LayoutContext } from './context';
|
||||
|
||||
export const DRAWER_WIDTH = 210;
|
||||
|
||||
const Layout: FC<RequiredChildrenProps> = ({ children }) => {
|
||||
const Layout: FC<RequiredChildrenProps> = memo(({ children }) => {
|
||||
const [mobileOpen, setMobileOpen] = useState(false);
|
||||
const [title, setTitle] = useState(PROJECT_NAME);
|
||||
const { pathname } = useLocation();
|
||||
|
||||
const handleDrawerToggle = () => {
|
||||
setMobileOpen(!mobileOpen);
|
||||
};
|
||||
// Memoize drawer toggle handler to prevent unnecessary re-renders
|
||||
const handleDrawerToggle = useCallback(() => {
|
||||
setMobileOpen((prev) => !prev);
|
||||
}, []);
|
||||
|
||||
useEffect(() => setMobileOpen(false), [pathname]);
|
||||
// Close drawer when route changes
|
||||
useEffect(() => {
|
||||
setMobileOpen(false);
|
||||
}, [pathname]);
|
||||
|
||||
// cache the object to prevent unnecessary re-renders
|
||||
const obj = useMemo(() => ({ title, setTitle }), [title]);
|
||||
// Memoize context value to prevent unnecessary re-renders
|
||||
const contextValue = useMemo(() => ({ title, setTitle }), [title]);
|
||||
|
||||
return (
|
||||
<LayoutContext.Provider value={obj}>
|
||||
<LayoutContext.Provider value={contextValue}>
|
||||
<LayoutAppBar title={title} onToggleDrawer={handleDrawerToggle} />
|
||||
<LayoutDrawer mobileOpen={mobileOpen} onClose={handleDrawerToggle} />
|
||||
<Box component="main" sx={{ marginLeft: { md: `${DRAWER_WIDTH}px` } }}>
|
||||
@@ -37,6 +41,6 @@ const Layout: FC<RequiredChildrenProps> = ({ children }) => {
|
||||
</Box>
|
||||
</LayoutContext.Provider>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default Layout;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { memo } from 'react';
|
||||
|
||||
import { Box, CircularProgress } from '@mui/material';
|
||||
|
||||
const LazyLoader = () => (
|
||||
const LazyLoader = memo(() => (
|
||||
<Box
|
||||
display="flex"
|
||||
justifyContent="center"
|
||||
@@ -15,6 +17,6 @@ const LazyLoader = () => (
|
||||
>
|
||||
<CircularProgress size={40} />
|
||||
</Box>
|
||||
);
|
||||
));
|
||||
|
||||
export default LazyLoader;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState } from 'react';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useBlocker } from 'react-router';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
@@ -35,20 +35,26 @@ export const useRest = <D>({ read, update }: RestRequestOptions<D>) => {
|
||||
setDirtyFlags([]);
|
||||
});
|
||||
|
||||
const updateDataValue = (new_data: D) => {
|
||||
// Memoize updateDataValue to prevent unnecessary re-renders
|
||||
const updateDataValue = useCallback(
|
||||
(new_data: D) => {
|
||||
updateData({ data: new_data });
|
||||
};
|
||||
},
|
||||
[updateData]
|
||||
);
|
||||
|
||||
const loadData = async () => {
|
||||
// Memoize loadData to prevent unnecessary re-renders
|
||||
const loadData = useCallback(async () => {
|
||||
setDirtyFlags([]);
|
||||
setErrorMessage(undefined);
|
||||
await readData().catch((error: Error) => {
|
||||
toast.error(error.message);
|
||||
setErrorMessage(error.message);
|
||||
});
|
||||
};
|
||||
}, [readData]);
|
||||
|
||||
const saveData = async () => {
|
||||
// Memoize saveData to prevent unnecessary re-renders
|
||||
const saveData = useCallback(async () => {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
@@ -64,14 +70,15 @@ export const useRest = <D>({ read, update }: RestRequestOptions<D>) => {
|
||||
setErrorMessage(error.message);
|
||||
}
|
||||
});
|
||||
};
|
||||
}, [data, writeData]);
|
||||
|
||||
return {
|
||||
loadData,
|
||||
saveData,
|
||||
saving: saving as boolean,
|
||||
updateDataValue,
|
||||
data: data as D, // Explicitly define the type of 'data'
|
||||
origData: origData as D, // Explicitly define the type of 'origData' to 'D'
|
||||
data: data as D,
|
||||
origData: origData as D,
|
||||
dirtyFlags,
|
||||
setDirtyFlags,
|
||||
setOrigData,
|
||||
|
||||
Reference in New Issue
Block a user