Context API
Context provides a way to pass data through the component tree without having to pass props down manually at every level.
We are using context for login methods - Auth0, JWT, Firebase, AWS.
SWR
SWR is a popular library for data fetching and state management in React applications. Data fetching is covered in section, here we are going to cover state management using SWR.
Mantis is managing the state of following using SWR
1. Snackbar
Snackbar is used to show notifications in the application. Whenever a component dispatches an action with data to show snackbar, it appears in the app. The initial state of snackbar is being captured using useSWR hooks and after that, we are mutating it state based on action calls. Following is the initial state:
VITE(TS) VITE(JS)
Copy const initialState: SnackbarProps = {
action: false,
open: false,
message: 'Note archived',
anchorOrigin: {
vertical: 'bottom',
horizontal: 'right'
},
variant: 'default',
alert: {
color: 'primary',
variant: 'filled'
},
transition: 'Fade',
close: false,
actionButton: false,
maxStack: 3,
dense: false,
iconVariant: 'usedefault'
};
Copy const initialState = {
action: false,
open: false,
message: 'Note archived',
anchorOrigin: {
vertical: 'bottom',
horizontal: 'right'
},
variant: 'default',
alert: {
color: 'primary',
variant: 'filled'
},
transition: 'Fade',
close: false,
actionButton: false,
maxStack: 3,
dense: false,
iconVariant: 'usedefault'
};
This values have been initialised using useSWR like below:
VITE(TS) VITE(JS)
Copy export function useGetSnackbar() {
const { data } = useSWR(endpoints.key, () => initialState, {
revalidateIfStale: false,
revalidateOnFocus: false,
revalidateOnReconnect: false
});
const memoizedValue = useMemo(() => ({ snackbar: data! }), [data]);
return memoizedValue;
}
Copy export function useGetSnackbar() {
const { data } = useSWR(endpoints.key, () => initialState, {
revalidateIfStale: false,
revalidateOnFocus: false,
revalidateOnReconnect: false
});
const memoizedValue = useMemo(() => ({ snackbar: data! }), [data]);
return memoizedValue;
}
Now how to read these values and update them as well.
To read the values and listen, following SWR hooks is sufficient in component. Whenever any changes happen, it activated like a redux selector and act based on logic.
VITE(TS) VITE(JS)
src/components/@extended /Snackbar.tsx
Copy ...
import { closeSnackbar, useGetSnackbar } from 'api/snackbar';
...
// animation options
const animation: KeyedObject = {
SlideLeft: TransitionSlideLeft,
SlideUp: TransitionSlideUp,
SlideRight: TransitionSlideRight,
SlideDown: TransitionSlideDown,
Grow: GrowTransition,
Fade
};
// ==============================|| SNACKBAR ||============================== //
export default function Snackbar() {
const { snackbar } = useGetSnackbar();
...
...
};
src/components/@extended /Snackbar.jsx
Copy ...
import { closeSnackbar, useGetSnackbar } from 'api/snackbar';
...
// animation options
const animation = {
SlideLeft: TransitionSlideLeft,
SlideUp: TransitionSlideUp,
SlideRight: TransitionSlideRight,
SlideDown: TransitionSlideDown,
Grow: GrowTransition,
Fade
};
// ==============================|| SNACKBAR ||============================== //
export default function Snackbar() {
const { snackbar } = useGetSnackbar();
...
...
};
To open the Snack bar, we need to change the value and mutate the state. Here is how it is done
VITE(TS) VITE(JS)
Copy export function openSnackbar(snackbar: SnackbarProps) {
// to update local state based on key
const { action, open, message, anchorOrigin, variant, alert, transition, close, actionButton } = snackbar;
mutate(
endpoints.key,
(currentSnackbar: any) => {
return {
...currentSnackbar,
action: action || initialState.action,
open: open || initialState.open,
message: message || initialState.message,
anchorOrigin: anchorOrigin || initialState.anchorOrigin,
variant: variant || initialState.variant,
alert: {
color: alert?.color || initialState.alert.color,
variant: alert?.variant || initialState.alert.variant
},
transition: transition || initialState.transition,
close: close || initialState.close,
actionButton: actionButton || initialState.actionButton
};
},
false
);
}
Copy export function openSnackbar(snackbar) {
// to update local state based on key
const { action, open, message, anchorOrigin, variant, alert, transition, close, actionButton } = snackbar;
mutate(
endpoints.key,
(currentSnackbar) => {
return {
...currentSnackbar,
action: action || initialState.action,
open: open || initialState.open,
message: message || initialState.message,
anchorOrigin: anchorOrigin || initialState.anchorOrigin,
variant: variant || initialState.variant,
alert: {
color: alert?.color || initialState.alert.color,
variant: alert?.variant || initialState.alert.variant
},
transition: transition || initialState.transition,
close: close || initialState.close,
actionButton: actionButton || initialState.actionButton
};
},
false
);
}
Then the method openSnackbar will be called from components to open snackbar.
VITE (TS) VITE (JS)
src/pages/apps/invoice /create.tsx
Copy ...
import { openSnackbar } from 'api/snackbar';
// types
import { SnackbarProps } from 'types/snackbar';
...
// ==============================|| INVOICE - CREATE ||============================== //
const Create = () => {
...
const handlerCreate = (values: any) => {
const newList: InvoiceList = {
...
};
...
openSnackbar({
open: true,
message: 'Invoice Added successfully',
anchorOrigin: { vertical: 'top', horizontal: 'right' },
variant: 'alert',
alert: {
color: 'success'
}
} as SnackbarProps);
...
};
return (
<MainCard>
...
</MainCard>
);
};
export default Create;
src/pages/apps/invoice /create.jsx
Copy ...
import { openSnackbar } from 'api/snackbar';
...
// ==============================|| INVOICE - CREATE ||============================== //
const Create = () => {
...
const handlerCreate = (values) => {
const newList: InvoiceList = {
...
};
...
openSnackbar({
open: true,
message: 'Invoice Added successfully',
anchorOrigin: { vertical: 'top', horizontal: 'right' },
variant: 'alert',
alert: {
color: 'success'
}
});
...
};
return (
<MainCard>
...
</MainCard>
);
};
export default Create;