我在React应用程序中遇到了一个问题,我向登录端点发出API调用.API的响应正确返回,表明身份验证成功.然而,我面临着两个问题:
apiData和isAuth状态没有及时更新,导致导航到登录页面的发生在这些状态更新之前. 因此,应用程序导航到登录页面过快,而没有等待状态更新.
使用Api钩
import axios, { AxiosResponse } from "axios";
import { useEffect, useRef, useState } from "react";
const useApi = <T,>(url: string, method: string, payload?: T) => {
const [apiData, setApiData] = useState<AxiosResponse>();
const [loading, setLoading] = useState(false);
const [error, setError] = useState();
useEffect(() => {
const getData = async () => {
try {
const response = await axios.request({
params: payload,
method,
url,
});
setApiData(response.data);
} catch (e) {
setError(e.message);
} finally {
setLoading(true);
}
};
getData();
}, []);
return { apiData, loading, error };
};
export default useApi;
这就是形式
import { useState } from "react";
import { useNavigate } from "react-router-dom";
export const SignIn = () => {
const [userInfo, setUserInfo] = useState({
user: "",
password: "",
});
const navigate = useNavigate();
const submitForm = (e) => {
e.preventDefault();
navigate("/user/sign-in", { state: userInfo });
};
const updateUser = (newVal: string) => {
setUserInfo((prev) => ({
...prev,
user: newVal,
}));
};
const updatePassword = (newVal: string) => {
setUserInfo((prev) => ({
...prev,
password: newVal,
}));
};
return (
<form onSubmit={(e) => submitForm(e)}>
<label>username</label>
<input type="text" onChange={(e) => updateUser(e.target.value)} />
<label htmlFor="">password</label>
<input type="password" onChange={(e) => updatePassword(e.target.value)} />
<button type="submit">submit</button>
</form>
);
};
privateRoute,我判断用户是否经过授权
import { useEffect, useState } from "react";
import useApi from "../../api/useApi";
import { Navigate, useLocation } from "react-router-dom";
import UserDashboard from "./UserDashboard";
export const PrivateRoute = () => {
const location = useLocation();
const { apiData, loading, error } = useApi(
import.meta.env.VITE_SIGN_IN,
"GET",
location.state,
);
const [isAuth, setAuth] = useState<boolean>(false);
useEffect(() => {
if (apiData?.status === 200) {
console.log(apiData, "api apiData");
setAuth(true);
}
}, [apiData]);
return (
<>
{isAuth ? (
<UserDashboard />
) : (
<Navigate to="/sign-in" state={{ from: location.pathname }} />
)}
</>
);
};