redux RTK查询,无效的挂钩调用,钩子只能在函数组件的主体内部调用,这可能是由于以下原因之一:

k4ymrczo  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(116)

我有一个组件LoginForm,在那里用户可以打开登录表单,并输入日期进入网站或注册。
我使用RTK查询和React钩子表单。
在这个组件中,我们感兴趣的是registerUser和loginIn,其他我已经删除

export const requestApi = createApi({
        reducerPath: 'requestApi',
        baseQuery: fetchBaseQuery({
            baseUrl: 'http://localhost:5000/',
            prepareHeaders: (headers:any) => {
                headers.set('authorization', localStorage.getItem('token'));
                return headers;
            },
        }),
        tagTypes: ['request'],
        endpoints: (builder) => ({
            registerUser: builder.mutation<any, any>({
                query: (params) => ({
                    url: '/auth/registration',
                    method: 'POST',
                    body: params,
                }),
            }),
            loginIn: builder.query<any, any>({
                query: (params) => ({
                    url: '/auth/login',
                    method: 'POST',
                    body: params,
                }),
            }),
        }),
    });
    
    export const {
        useGetSortedFilmQuery,
        useRegisterUserMutation,
        useLoginInQuery,
        useGetInfoUserQuery,
        useAddFilmQuery,
    } = requestApi;

下一个。
下面是组件LoginForm。我已经从组件中删除了,所有我们不需要的。
在这个组件中,我有函数registerIn,我可以使用它。这个函数在钩子useRegisterUserMutation中。
但是在其他的钩子useLoginInQuery中,我没有这样的函数,我必须在body组件中使用钩子,但是我想在函数里面使用。
让我们看看组件。
如何正确地发送登录请求,如果我使用RTK查询,我必须在组件的顶部使用钩子。
当我在组件的主体中使用钩子useLoginInQuery时,这并不好,因为每次打开表单时都会发送请求(我什么也没写)。或许我做错了什么?

export const LoginForm:FC<LoginFormProps> = (props) => {

        // here I've function registerIn
        const [registerIn, {
            data: requestRegister, error: errorRegister, isError: isErrorRegister, isLoading: loadingRegister,
        }] = useRegisterUserMutation();

        // here I don't have function
        const {
            data: userLogin, isError: isErrorLogin, isLoading: loadLogin, error: errorLogin,
        } = useLoginInQuery({ phoneNumber: element.mailOrNumberLoginIn, password: element.passwordLogin });

        // React hook form
        const {
            register, handleSubmit, setError, formState: { errors, isValid },
        } = useForm<loginForm>({
            mode: 'onChange',
        });

        // Here it's working well
        const sendRegisterForm = (element:any) => {
            if (Number.isFinite(+element.mailOrNumberRegistration.replace('+', ''))) {
                registerIn({ phoneNumber: element.mailOrNumberRegistration, password: element.passwordRegistration });
            } else {
                registerIn({ email: element.mailOrNumberRegistration, password: element.passwordRegistration });
            }
        };

        // But here I see problem: Invalid hook call. Hooks can only be called inside of the body of a function component. 
        const sendLoginForm = (element:any) => {
            if (Number.isFinite(+element.mailOrNumberLoginIn.replace('+', ''))) {
                const {
                    data: userLogin, isError: isErrorLogin, isLoading: loadLogin, error: errorLogin,
                } = useLoginInQuery({ phoneNumber: element.mailOrNumberLoginIn, password: element.passwordLogin });
                console.log(userLogin);
            } else {
                const {
                    data: userLogin, isError: isErrorLogin, isLoading: loadLogin, error: errorLogin,
                } = useLoginInQuery({ email: element.mailOrNumberLoginIn, password: element.passwordLogin });
                console.log(userLogin);
            }
        };

        //when I send form
        const onSubmit: SubmitHandler<loginForm> = (data) => {
            // console.log(data);
            if (clickOnEnter === 0) {
                sendLoginForm(data);
            }
            if (clickOnEnter === 1) {
                sendRegisterForm(data);
                // if (requestRegister && requestRegister.message === 'Учетная запись создана') {
                //     dispatch(changeStateClickOnEnter(3));
                // }
            }
        };
    
      
        return (
            <div className={classNames(cls.LoginForm, {}, [classname])}>
                { clickOnEnter === 0
                    && (
                        <form
                            className={cls.form}
                            onSubmit={handleSubmit(onSubmit)}
                            onChange={checkTextFormsLogin}
                        >
                            <h2
                                className={cls.title}
                            >
                                {t('Вход в учетную запись')}
                            </h2>
                            <div className={cls.inputsForm}>
                                <Input
                                    type={loginsText.loginWindow}
                                    classForInput={cls.input}
                                    placeholder="Логин или номер телефона"
                                    autofocus
                                    defaultValue={textFromForms.loginIn}
                                    autoComplete="login"
                                    forRef={loginRef}  
                                    register={{ ...register('mailOrNumberLoginIn') }}
                                />
                                <Input
                                    classForInput={cls.input}
                                    type={passwordHideButton.loginShowHide ? 'text' : 'password'}
                                    placeholder="Пароль"
                                    defaultValue={textFromForms.passwordLogin}
                                    autoComplete="password"
                                    forRef={passwordLoginRef}
                                    register={{ ...register('passwordLoginIn') }}
                                >
                                    {
                                        passwordHideButton.login
                                        && (
                                            <Button
                                                type="button"
                                                className={cls.hideButton}
                                                onClick={showAndHideTextLoginInPassword}
                                            >
                                                {!passwordHideButton.loginShowHide ? <ShowSvg className={cls.showSvg} /> : <HideSvg className={cls.hideSvg} />}
                                            </Button>
                                        )
                                    }
                                </Input>
                            </div>
                            <div className={cls.btnCover}>
                                <div className={cls.blockAdditional}>
                                    <Button
                                        className={cls.profileRegistration}
                                        onClick={changeStateEnterOrRegister}
                                    >
                                        { t('Нет учетной записи')}
                                    </Button>
                                    <Button
                                        className={cls.forgetPassword}
                                        onClick={openWindowRecoveryAccess}
                                    >
                                        { t('Забыли логин или пароль')}
                                    </Button>
                                </div>
                                <div className={cls.button}>
                                    <Button
                                        className={cls.btnEnter}
                                        type="submit"
                                    >
                                        { t('Войти')}
                                    </Button>
                                </div>
                            </div>
                        </form>
                    )}
                { clickOnEnter === 1
                    && (
                        <form
                            className={cls.form}
                            onSubmit={handleSubmit(onSubmit)}
                            onChange={checkTextFormsRegistration}
                        >
                            <h2
                                className={cls.title}
                            >
                                {t('Регистрация')}
                            </h2>
                            <div className={cls.inputsForm}>
                                <Input
                                    type="text"
                                    classForInput={cls.input}
                                    placeholder="Логин или номер телефона"
                                    autofocus
                                    defaultValue={textFromForms.loginRegister}
                                    disabled={loadingRegister && true}
                                    forRef={loginRegisterRef}
                                />
                                <Input
                                    classForInput={cls.input}
                                    type={passwordHideButton.registerShowHide ? 'text' : 'password'}
                                    placeholder="Пароль"
                                    defaultValue={textFromForms.passwordRegister}
                                    disabled={loadingRegister && true}
                                    forRef={passwordRegisterRef}
                                    register={{ ...register('passwordRegistration') }}
                                    onInput={addTextFromRegistrationForm}
                                >
                                    {
                                        passwordHideButton.register
                                        && (
                                            <Button
                                                type="button"
                                                className={cls.hideButton}
                                                onClick={showAndHideTextRegistrationPassword}
                                            >
                                                {!passwordHideButton.registerShowHide ? <ShowSvg className={cls.showSvg} /> : <HideSvg className={cls.hideSvg} />}
                                            </Button>
                                        )
                                    }
                                </Input>
                            </div>
                            <div className={cls.btnCoverTwo}>
                                <Button
                                    className={cls.btnEnter}
                                    onClick={backToLoginIn}
                                    type="button"
                                >
                                    { t('Вернуться')}
                                </Button>
                                <Button
                                    className={cls.btnEnter}
                                    type="submit"
                                >
                                    { t('Создать учетную запись')}
                                </Button>
                            </div>
                        </form>
                    )}
            </div>
        );
    };
nkhmeac6

nkhmeac61#

你需要使用login作为一个变量,就像你做的注册变量一样,你可以在sendLoginForm中调用它的方法。

loginIn: builder.mutation<any, any>({
            query: (params) => ({
                url: '/auth/login',
                method: 'POST',
                body: params,
            }),
        }),
.....
export const {
    useGetSortedFilmQuery,
    useRegisterUserMutation,
    useLoginInMutation,
    useGetInfoUserQuery,
    useAddFilmQuery,
} = requestApi;

在LoginForm中,您可以像这样使用它

const [login, {
            data: loginData, error: errorLogin, isError: isErrorLogin, isLoading: loadingLogin,
        }] = useLoginInMutation();

在sendLoginForm函数中,可以调用方法login

const sendLoginForm = (element:any) => {
        if (Number.isFinite(+element.mailOrNumberLoginIn.replace('+', ''))) {
            login({ phoneNumber: element.mailOrNumberLoginIn, password: element.passwordLogin });
        } else {
            login({ email: element.mailOrNumberLoginIn, password: element.passwordLogin });
        }
    };

相关问题