为什么React保护路线第二次在反冲状态下工作



我正在用Recoil和React Router(两者都用Typescript(构建一个小型Recipe应用程序。我的目标是用Recoil将布尔值设置为"loginState",作为受保护路由组件准备导航的指示。

我正试图在登录组件中将useSetRecoilStateloginState设置为true,并重定向到路由,但当反冲状态更新时,ProtectedRoute组件将重定向回入口页面,因为loginState将为false(听起来很合理(。

因此,它只能在第二次工作,请单击它。保持身份验证的正确解决方案是否需要在localStorage上?或者我需要以某种方式等待反冲来更新loginState

我还使用了建议的DebugObserver反冲来检查状态更新日志。

以下是我的代码:

存储.ts

export const loginState = atom({
key: "loginState",
default: false, 
});

Onboarding.ts(在原子onClick上设置true,并重定向到"/main"路由(

const Onboarding = () => {
const history = useHistory();
const setLogin = useSetRecoilState(loginState);
return (
<div className="Onboarding">
<div className="DishesContainer">
<img src={Dishes} alt="" />
</div>
<div className="description">
<h2>Start Cooking</h2>
<p className="p1">Let’s join our community
to cook better food!
</p>
</div>
<div className="GetStartedContainer">
<AppButton text="Get Started" onClick={() => {
setLogin(true);
history.push("/main");
}} />
</div>
</div>
)
};

受保护的路由.ts

export const ProtectedRoute = (props: RouteProps) => {
const isLoggedIn = useRecoilValue(loginState);
const authenticationPath = "/";

if (isLoggedIn) {
return <Route {...props} />;
} else {
return <Redirect to={{ pathname: authenticationPath }} />;
}
};

状态更新是异步的,这对于反冲useState和反冲状态更新都是如此。

你打电话给

setLogin(true);
history.push("/main");

单击按钮,但当新路由被推送到路由器时,loginState可能仍设置为false。由于您无法知道setLogin调用何时解析为具有新状态的新渲染(React 18尤其如此,因为默认情况下启用了并发渲染(,因此您必须使用useEffect,它在loginState更改时触发,如下所示:

const Onboarding = () => {
const history = useHistory();
const [isLoggedIn, setLogin] = useRecoilState(loginState);
useEffect(() => {
if (isLoggedIn) {
history.push("/main");
}
}, [isLoggedIn]);
return (
<div className="Onboarding">
<div className="DishesContainer">
<img src={Dishes} alt="" />
</div>
<div className="description">
<h2>Start Cooking</h2>
<p className="p1">Let’s join our community
to cook better food!
</p>
</div>
<div className="GetStartedContainer">
<AppButton text="Get Started" onClick={() => {
setLogin(true);
}} />
</div>
</div>
)
};

最新更新