Skip to content

Commit

Permalink
feat: add force update to change design without reload
Browse files Browse the repository at this point in the history
  • Loading branch information
sashtje committed Oct 16, 2023
1 parent 7b29f6b commit 9cc9ed3
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 20 deletions.
6 changes: 4 additions & 2 deletions src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ export function App() {
const inited = useSelector(getUserInited);

useEffect(() => {
dispatch(initAuthData());
}, [dispatch]);
if (!inited) {
dispatch(initAuthData());
}
}, [dispatch, inited]);

if (!inited) {
return <PageLoader />;
Expand Down
5 changes: 4 additions & 1 deletion src/features/authByUsername/ui/LoginForm/LoginForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { useAppDispatch } from '@/shared/lib/hooks/useAppDispatch/useAppDispatch
import { useTheme } from '@/shared/lib/hooks/useTheme/useTheme';
import { ToggleFeatures } from '@/shared/lib/features';
import { VStack } from '@/shared/ui/redesigned/Stack';
import { useForceUpdate } from '@/shared/render/forceUpdate';

import { getLoginUsername } from '../../model/selectors/getLoginUsername/getLoginUsername';
import { getLoginPassword } from '../../model/selectors/getLoginPassword/getLoginPassword';
Expand Down Expand Up @@ -46,6 +47,7 @@ export const LoginForm = memo((props: LoginFormProps) => {
const password = useSelector(getLoginPassword);
const isLoading = useSelector(getLoginIsLoading);
const error = useSelector(getLoginError);
const forceUpdate = useForceUpdate();
const { setTheme } = useTheme();

const onChangeUsername = useCallback(
Expand All @@ -70,8 +72,9 @@ export const LoginForm = memo((props: LoginFormProps) => {
setTheme?.(result.payload.jsonSettings.theme);
}
onSuccess();
forceUpdate();
}
}, [onSuccess, dispatch, password, username, setTheme]);
}, [onSuccess, dispatch, password, username, setTheme, forceUpdate]);

return (
<DynamicModuleLoader reducers={initialReducers} removeAfterUnmount>
Expand Down
6 changes: 5 additions & 1 deletion src/features/uiDesignSwitcher/ui/UiDesignSwitcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { getUserAuthData } from '@/entities/User';
import { HStack } from '@/shared/ui/redesigned/Stack';
import { Text } from '@/shared/ui/redesigned/Text';
import { Skeleton } from '@/shared/ui/redesigned/Skeleton';
import { useForceUpdate } from '@/shared/render/forceUpdate';

interface UiDesignSwitcherProps {
className?: string;
Expand All @@ -20,6 +21,7 @@ export const UiDesignSwitcher = memo((props: UiDesignSwitcherProps) => {
const dispatch = useAppDispatch();
const authData = useSelector(getUserAuthData);
const [isLoading, setIsLoading] = useState(false);
const forceUpdate = useForceUpdate();

const isAppRedesigned = getFeatureFlag('isAppRedesigned');
const items = useMemo(
Expand Down Expand Up @@ -50,10 +52,12 @@ export const UiDesignSwitcher = memo((props: UiDesignSwitcherProps) => {
}),
).unwrap();

forceUpdate();

setIsLoading(false);
}
},
[authData?.id, dispatch],
[authData?.id, dispatch, forceUpdate],
);

return (
Expand Down
10 changes: 6 additions & 4 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { App } from '@/app/App';
import { ThemeProvider } from '@/app/providers/ThemeProvider';
import { ErrorBoundary } from '@/app/providers/ErrorBoundary';
import { StoreProvider } from '@/app/providers/StoreProvider';

import '@/app/styles/index.scss';
import '@/shared/config/i18n/i18n';
import { ForceUpdateProvider } from '@/shared/render/forceUpdate';

const container = document.getElementById('root');

Expand All @@ -20,9 +20,11 @@ root.render(
<BrowserRouter>
<StoreProvider>
<ErrorBoundary>
<ThemeProvider>
<App />
</ThemeProvider>
<ForceUpdateProvider>
<ThemeProvider>
<App />
</ThemeProvider>
</ForceUpdateProvider>
</ErrorBoundary>
</StoreProvider>
</BrowserRouter>,
Expand Down
14 changes: 8 additions & 6 deletions src/shared/lib/features/services/updateFeatureFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createAsyncThunk } from '@reduxjs/toolkit';
import { ThunkConfig } from '@/app/providers/StoreProvider';
import { updateFeatureFlagsMutation } from '@/shared/lib/features/api/featureFlagsApi';
import { FeatureFlags } from '@/shared/types/featureFlags';
import { getAllFeatureFlags } from '@/shared/lib/features/lib/setGetFeatures';
import { getAllFeatureFlags, setFeatureFlags } from '@/shared/lib/features/lib/setGetFeatures';

interface UpdateFeatureFlagsArg {
userId: string;
Expand All @@ -17,18 +17,20 @@ export const updateFeatureFlags = createAsyncThunk<
>('features/updateFeatureFlags', async ({ userId, newFeatures }, thunkAPI) => {
const { rejectWithValue, dispatch } = thunkAPI;

const allFeatures = {
...getAllFeatureFlags(),
...newFeatures,
};

try {
await dispatch(
updateFeatureFlagsMutation({
userId,
features: {
...getAllFeatureFlags(),
...newFeatures,
},
features: allFeatures,
}),
);

window.location.reload();
setFeatureFlags(allFeatures);

return undefined;
} catch (e) {
Expand Down
31 changes: 31 additions & 0 deletions src/shared/render/forceUpdate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { createContext, ReactNode, useCallback, useContext, useMemo, useState } from 'react';

const ForceUpdateContext = createContext({
value: true,
forceUpdate: () => {},
});

export const useForceUpdate = () => {
const { forceUpdate } = useContext(ForceUpdateContext);

return forceUpdate;
};

export function ForceUpdateProvider({ children }: { children: ReactNode }) {
const [value, setValue] = useState(true);

const forceUpdate = useCallback(() => {
setValue((prev) => !prev);
setTimeout(() => {
setValue((prev) => !prev);
}, 0);
}, []);

const contextValue = useMemo(() => ({ value, forceUpdate }), [value, forceUpdate]);

if (!value) {
return null;
}

return <ForceUpdateContext.Provider value={contextValue}>{children}</ForceUpdateContext.Provider>;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createSelector } from '@reduxjs/toolkit';
import { useSelector } from 'react-redux';

import { getUserAuthData } from '@/entities/User';
import MainIconDeprecated from '@/shared/assets/icons/main-20-20.svg';
Expand All @@ -20,7 +20,9 @@ import { toggleFeatures } from '@/shared/lib/features';

import { SidebarItemType } from '../types/sidebar';

export const getSidebarItems = createSelector(getUserAuthData, (userData) => {
export const useSidebarItems = () => {
const userData = useSelector(getUserAuthData);

const sidebarItemsList: SidebarItemType[] = [
{
path: getRouteMain(),
Expand Down Expand Up @@ -72,4 +74,4 @@ export const getSidebarItems = createSelector(getUserAuthData, (userData) => {
}

return sidebarItemsList;
});
};
5 changes: 2 additions & 3 deletions src/widgets/Sidebar/ui/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { memo, useState } from 'react';
import { useSelector } from 'react-redux';

import { classNames } from '@/shared/lib/classNames';
import { Button, ButtonSize, ButtonTheme } from '@/shared/ui/deprecated/Button';
Expand All @@ -11,7 +10,7 @@ import { AppLogo } from '@/shared/ui/redesigned/AppLogo';
import { Icon } from '@/shared/ui/redesigned/Icon';
import ArrowIcon from '@/shared/assets/icons/arrow-bottom.svg';

import { getSidebarItems } from '../../model/selectors/getSidebarItems';
import { useSidebarItems } from '../../model/selectors/useSidebarItems';
import { SidebarItem } from '../SidebarItem/SidebarItem';
import cls from './Sidebar.module.scss';

Expand All @@ -21,7 +20,7 @@ interface SidebarProps {

export const Sidebar = memo(({ className }: SidebarProps) => {
const [collapsed, setCollapsed] = useState(false);
const sidebarItemsList = useSelector(getSidebarItems);
const sidebarItemsList = useSidebarItems();

const onToggle = () => {
setCollapsed((prev) => !prev);
Expand Down

0 comments on commit 9cc9ed3

Please sign in to comment.