reactjs - omslut useDispatch och useAppSelector med egna hooks


Jag har följande funktioner och komponenter i mitt projekt:

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;

Anta att jag i mitt projekt från en av mina komponenter, som kallas AuthDialog, vill använda useDispatch och dispatcha en åtgärd som denna:

    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>
}

Om jag vill kalla på TOGGLE_AUTH_DIALOG-åtgärden överallt där den används, bör jag upprepa dessa kodrader:

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

Så jag bestämde mig för att göra det bättre och, istället för att upprepa de nämnda koderna, skapa en hook för varje åtgärd som jag vill skicka, som:

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;
}
 

Efter att jag gjort det, skulle AuthDialog ändras till:

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>
}

Slutligen, kan den här typen av förändring påverka prestandan i min kod? Är det något bra eller inte? För när jag har många anpassade hooks är det upprepande att hämta state från useAppSelector, och om jag vill använda flera hooks i komponenterna bör jag skriva något som:

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