我正在React Router上构建一个(我认为(应该是简单的访问保护,以根据用户是否可以访问该规范来保护路由/spec/:id
上的给定spec
。用户对规范的访问通过其id: string
是否出现在规范的shared: string[]
字段中来表示
当用户没有访问权限时,预期的行为是将他们重定向到/
的主页。在下面的情况中,用户没有访问权限,相反,我留在/spec/:id
,控制台中没有任何错误。有人能指出为什么会出现这种情况吗?非常感谢
import { useContext, useEffect, useState } from "react";
import { Redirect, Route, useParams } from "react-router-dom";
import { getSpecById } from "../Models/Spec";
import { AuthContext } from "../Util/Auth";
const ProtectedRoute = ({ component: Component, ...rest }: any) => {
const { id } = useParams<{ id: string }>();
const {currentUser} = useContext(AuthContext);
const [isOwner, setIsOwner] = useState<boolean>(false);
useEffect(() => {
async function fetchOwnership() {
const specData = await getSpecById(id);
if (specData && currentUser) {
console.log(specData.shared.includes(currentUser.uid)); //logs false
setIsOwner(specData.shared.includes(currentUser.uid));
}
}
fetchOwnership();
});
return (
<Route
{...rest}
render={(routeProps: any) => {
isOwner ? (
<Component {...routeProps} />
) : (
<Redirect to={"/"} />
)
}}
/>
)
};
export default ProtectedRoute
我打电话给<ProtectedRoute>
<ProtectedRoute exact path="/spec/:id" render={() => (<Spec isEdit={true}/> )}/>
EDIT根据Jason的反馈,我重新设计了包含isOwner
的状态变量,以使用useRef()
。但是Redirect
仍然没有被调用。即使isOwner
等于false
,我也不会被送回"/"
const ProtectedRoute = ({ component: Component, ...rest }: any) => {
const { id } = useParams<{ id: string }>();
const {currentUser} = useContext(AuthContext);
const isOwner = useRef(null);
useEffect(() => {
async function fetchOwnership() {
const specData = await getSpecById(id);
if (specData && currentUser) {
isOwner.current = specData.shared.includes(currentUser.uid);
}
}
fetchOwnership();
});
console.log(isOwner.current);
if (isOwner.current === undefined) {
return null;
}
return (
<Route
{...rest}
render={(routeProps: any) => {
isOwner.current ? (
<Component {...routeProps} />
) : (
<Redirect to={"/"} />
)
}}
/>
)
};
似乎根本没有调用重定向。在第一次渲染中,isOwner
为false(useState的默认值(,因此应该立即重定向(如果一切正常(;
我假设Route
标记没有呈现其子级。是从{...rest}
给它一个path
道具吗?
不能直接调用useEffect钩子内的异步函数,必须使用IIFE方法。这是我用过的一个例子。
useEffect(() => {
(async () => {
const users = await axios.get("https://randomuser.me/api/?page=1&results=10&nat=us");
setUsers(users.data.results);
})();
}, []);
在您的情况下是
useEffect(() => {
async function fetchOwnership() {
const specData = await getSpecById(id);
if (specData && currentUser) {
console.log(specData.shared.includes(currentUser.uid)); //logs false
setIsOwner(specData.shared.includes(currentUser.uid));
}
}()
});