Estoy trabajando en un código de inicio de sesión y quiero agregar la funcionalidad para verificar si el usuario es administrador o no. Sé que no puedo llamar a un gancho dentro de una devolución de llamada, y he verificado otras respuestas en SO, pero aún no puedo entender cómo usar la funcionalidad del gancho. El problema es que debe activarse desde la función de envío de un formulario, por lo que no puedo llamarlo en el nivel superior de mi componente React, como sugiere el mensaje de error. ( React Hooks must be called in a React function component or a custom React Hook function react-hooks/rules-of-hooks )
¿Alguien puede ayudarme a descubrir cómo refactorizar este código para obtener la funcionalidad del enlace en una devolución de llamada?
Descripción del código:
Componente de inicio de sesión: es un formulario con una función onSubmit , que llama a una función de inicio de signIn personalizada.
función de signIn de sesión: toma usuario/contraseña y una función de devolución de llamada para ser llamada solo si el flujo de autenticación tiene éxito.
hook useCheckUserAdmin - comprueba si el usuario es un administrador. Idealmente llamado dentro de la devolución de llamada de signIn .
Función onSuccess : redirige a la página de inicio del administrador o del cliente. llamado dentro de la devolución de llamada de signIn , justo después del gancho.
Código real:
Aquí está el componente principal de inicio de sesión (tenga en cuenta que se eliminaron algunas piezas irrelevantes), incluida la función onSuccess
const SignInComponent = () => { const onSuccess = React.useCallback( (userIsAdmin) => { // history.replace(etc. etc.) <- some boolean logic to direct to an admin or a regular user page }, [] ); return <Formik onSubmit={async (values) => { await signIn(values.username, values.password, (userId) => { const userIsAdmin = useCheckUserAdmin(userId) onSuccess(userIsAdmin); setError(null); }).catch((err) => { setError(err.message); }); }} > } El enlace personalizado useCheckUserAdmin (simplificado para facilitar la lectura):
import { useGetUser } from "../api/composedHooks"; export default function useCheckUserAdmin(userId: string) { const userQuery = useGetUser({ variables: { id: userId }, }); return userQuery.userType; }La función de inicio de sesión:
async function signIn( username: string, password: string, callback: (userId: string) => void ) { try { const result = await Auth.signIn({ username, password, }); if (result) { return callback(result.username); } } catch (error) { console.error("error signing in:", error); throw error; } }Realmente no hay forma de llamar al gancho personalizado en su devolución de llamada (ya que falla las reglas de verificación de ganchos). Si debe realizar esta lógica dentro de un enlace personalizado (lo que puede no ser necesario ya que no veo por qué requiere una lógica con estado), una opción sería devolver la función necesaria desde el enlace personalizado:
SignInComponent = () => { const checkUserIsAdmin = useCheckUserIsAdmin() // non-conditionally call the hook }Luego, en su devolución de llamada, algo como:
callback(checkUserIsAdmin)Y su gancho personalizado llama a los ganchos necesarios y devuelve la función:
// Call any needed hooks (useLocation..useHistory..etc) const checkUserIsAdmin = () => {...logic operating on userId} return checkUserIsAdminNo estoy seguro de si ayuda, pero es una forma de satisfacer las condiciones de su problema.