Búsqueda de sitios web

reactjs - envolver useDispatch y useAppSelector con hooks personalizados


Tengo las siguientes funciones y componentes en mi proyecto:

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;

Supongamos que en mi proyecto, desde uno de mis componentes, que se llama AuthDialog, quiero usar useDispatch y despachar una acción así:

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

Si quiero llamar a la acción TOGGLE_AUTH_DIALOG en todos los lugares donde se utiliza, debo repetir estas líneas de código:

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

Así que decidí mejorarlo y, en lugar de repetir los códigos mencionados, crear un hook para cada acción que quiero despachar, como:

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

Después de que lo hice, AuthDialog se cambiaría a:

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

Finalmente, ¿puede este tipo de cambio afectar el rendimiento de mi código? ¿Es algo bueno o no? Porque cuando tengo muchos hooks personalizados, obtener el estado desde useAppSelector se repite, y si quiero usar múltiples hooks en los componentes, debería escribir algo como:

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