'wrap useDispatch and useAppSelector with custom hooks

I have following functions and components in my project:

store.ts :

import { combineReducers, createStore } from 'redux';
import { configureStore } from '@reduxjs/toolkit';
import { authDialogReducer } from './authentication/authenticationReducer';
import { toastReducer } from './toast/toastReducer';

const rootReducer = combineReducers({
    authDialog: authDialogReducer,
    toast: toastReducer
})

export const store = configureStore({
    reducer: rootReducer
})

export type AppState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

hooks.ts :

import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
import { AppDispatch, AppState } from './store';

export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<AppState> = useSelector;

Suppose in my project from one of my components which is called AuthDialog I want to use useDispatch and dispatch a action like this:

    const AuthDialog: React.FunctionComponent<AuthDialogProps> = (props) => {
    const authDialogState = useAppSelector((state) => state.authDialog);
    const dispatch = useAppDispatch();
    const dispatchAuthDialog = (isOpen: boolean) => {
        dispatch({ payload: { isOpen: isOpen }, type: TOGGLE_AUTH_DIALOG } as ToggleAuthDialog)
    };
    const onCloseDialogClick = () => {
        dispatchAuthDialog(false);
    }
    const onSubmitClick = (e: React.MouseEvent<HTMLElement>) => {

    }

    const onTabChange = (e: React.ChangeEvent<{}>, newValue: number) => {

    }

    return <Dialog className={Classes.Root} open={authDialogState.isOpen}>
        <DialogContent className={Classes.Content}>
            <div className={Classes.AuthDialogIcon}>
                <LockOpen />
            </div>
            <AuthDialogTabs onTabChange={onTabChange} />
        </DialogContent>
        <DialogActions>
            <ButtonGroup>
                <CommonButton color="danger" onClick={onCloseDialogClick} title="خروج" />
                <CommonButton color="success" onClick={onSubmitClick} title="ثبت" />
            </ButtonGroup>
        </DialogActions>
    </Dialog>
}

If I want to call TOGGLE_AUTH_DIALOG action in everywhere that is used, I should repeat these line of codes:

const authDialogState = useAppSelector((state) => state.authDialog);
const dispatch = useAppDispatch();
const dispatchAuthDialog = (isOpen: boolean) => {
    dispatch({ payload: { isOpen: isOpen }, type: TOGGLE_AUTH_DIALOG } as ToggleAuthDialog)
};

So I decided to make it better and instead of repeating mentioned codes, create a hook for each every action that I want to dispatch like:

export const useAuthDialog: () => readonly [AuthDialogState, (isOpen: boolean) => void] = () => {
    const authDialogState = useAppSelector((state) => state.authDialog);
    const dispatch = useAppDispatch();
    const dispatchAuthDialog = (isOpen: boolean) => {
        dispatch({ payload: { isOpen: isOpen }, type: TOGGLE_AUTH_DIALOG } as ToggleAuthDialog)
    };
    return [authDialogState, dispatchAuthDialog] as const;
}
 

After I did, AuthDialog would be changed to:

const AuthDialog: React.FunctionComponent<AuthDialogProps> = (props) => {
    const [authDialogState, toggleAuthDialog] = useAuthDialog();
    const onCloseDialogClick = () => {
        toggleAuthDialog(false);
    }
    const onSubmitClick = (e: React.MouseEvent<HTMLElement>) => {

    }

    const onTabChange = (e: React.ChangeEvent<{}>, newValue: number) => {

    }

    return <Dialog className={Classes.Root} open={authDialogState.isOpen}>
        <DialogContent className={Classes.Content}>
            <div className={Classes.AuthDialogIcon}>
                <LockOpen />
            </div>
            <AuthDialogTabs onTabChange={onTabChange} />
        </DialogContent>
        <DialogActions>
            <ButtonGroup>
                <CommonButton color="danger" onClick={onCloseDialogClick} title="خروج" />
                <CommonButton color="success" onClick={onSubmitClick} title="ثبت" />
            </ButtonGroup>
        </DialogActions>
    </Dialog>
}

Finally, I want to know that this kind of changes can affect the performance of my code? Is it a good thing or not? Because when I have a lots of custom hooks, getting state from useAppSelector is repeating and If I want to use multiple hook in the components, I should write something like:

const [authDialogState, toggleAuthDialog] = useAuthDialog();
const [toastState, toastDialog] = useSuccessToast();


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source