我创建了一个登录表单,用户需要在其中输入他的电子邮件 ID 和 OTP。下面是我的代码 -
import { useState } from 'react';
import axios from '../api/axios';
const useLogin = () => {
const [user, setUser] = useState(false);
const auth = async (value, OTP) => {
let config = {
method: 'POST',
url: '/api/user/generateToken',
headers: {
Authorization: 'value'
},
data: {
username: value,
password: OTP
}
};
try {
const response = await axios(config);
if (response.data.Status === "Failure") {
throw response.data.Message;
} else {
setUser(true);
return { status: response.data.Status, isAuth: user }
}
} catch (err) {
setUser(false);
return { status: undefined, message: err, isAuth: user };
}
}
return { auth, user };
}
export default useLogin
这里一切正常,唯一的问题是当我在我的组件中调用这个函数时,我会收到 isAuth 总是假的。下面是我的组件代码 -
import React, { Fragment, useRef, useEffect, useState } from 'react';
import { useLocation, useHistory } from "react-router-dom";
import { css } from "@emotion/core";
import ScaleLoader from "react-spinners/ScaleLoader";
import '../css/login.css';
import '../css/common.css';
import logo from '../assets/engageLogo.png';
import * as Yup from 'yup';
import { useFormik } from 'formik';
import useLogin from './../hooks/useOTP';
const override = css`
display: block;
margin: 0 auto;
border-color: #fff;
`;
const OTP = () => {
const [loading, setLoading] = useState(false);
const [color] = useState("#ffffff");
const [APIResponse, setAPIResponse] = useState(false);
const [APIMessage, setAPIMessage] = useState('')
const login = useLogin();
const location = useLocation();
const history = useHistory();
const inputRef = useRef();
const readRef = useRef();
const buttonRef = useRef();
const schema = Yup.object({
otp: Yup.string().required("OTP is Required")
});
const handleChangeError = () => {
return setAPIResponse(false)
}
const {
handleSubmit,
handleChange,
handleBlur,
touched,
errors,
} = useFormik({
initialValues: {
otp: "",
},
validationSchema: schema,
onSubmit: (values) => {
console.log(JSON.stringify(values));
buttonRef.current.disabled = true;
setLoading(true);
const loginCall = login.auth(location.state.email, values.otp);
loginCall.then(response => {
if (response.status === undefined || response.status === null) {
setLoading(false);
buttonRef.current.disabled = false;
setAPIResponse(true)
setAPIMessage(response.message)
} else {
setLoading(false);
history.push({
pathname: '/dashboard',
state: { email: values.email }
});
}
})
},
});
useEffect(() => {
inputRef.current.focus();
readRef.current.value = location.state.email;
}, [location])
return <Fragment>
<div className="centered-form">
<div className="centered-form__box">
<div className="mb-3 text-center">
<img src={logo} className="img-fluid" width="150" alt="Logo" />
</div>
<form onSubmit={handleSubmit} noValidate>
<div className="mb-3">
<label htmlFor="readEmail" className="form-label">Email</label>
<input
type="text"
name="readEmail"
id="readEmail"
ref={readRef}
className="form-control" readOnly />
</div>
<div className="mb-3">
<label htmlFor="otp" className="form-label">OTP</label>
<input
type="text"
name="otp"
id="otp"
ref={inputRef}
onChange={(e) => { handleChange(e); handleChangeError(e) }}
onBlur={handleBlur}
className="form-control" placeholder="Enter OTP" required />
{touched.otp && errors.otp
? <div className="invalid-feedback">Please enter valid OTP</div>
: null}
{APIResponse
? <div className="invalid-feedback">{APIMessage}</div>
: null}
</div>
<div className="d-grid gap-2">
<button ref={buttonRef} className="btn btn-main">{loading ?
<ScaleLoader color={color} loading={loading} css={override} height={15} /> : <span>Login</span>}</button>
</div>
</form>
</div>
</div>
</Fragment>
}
export default OTP
在 response
的 loginCall
中,我总是会得到 isAuth: false
。
我想使用 isAuth 来保护我的路线。只是为了检查用户是否已登录。
为什么 setUser
没有更新此处的值。
提前致谢...
答案 0 :(得分:1)
那是因为当您返回 isAuth
值时,new user value
尚未设置。您需要知道 React setState
是异步函数。
只需像这样直接使用布尔值本身:
setUser(true);
return { status: response.data.Status, isAuth: true }
或者在被拒绝的情况下:
setUser(false);
return { status: undefined, message: err, isAuth: false };