我有这个钩子:
export const authenticationReducer = (
state: { busy: boolean; isAuthenticated: boolean },
action: AuthenticatedActions
) => {
switch (action.type) {
case AuthenticatedActionTypes.SetIsAuthenticated: {
return { ...action.payload };
}
case AuthenticatedActionTypes.SetBusy: {
return { ...state, busy: action.payload.busy };
}
default:
throw new Error(`no case for ${action} in AuthenticationReducer`);
}
};
export const useIsUserAuthenticated = () => {
const [{ busy, isAuthenticated }, dispatch] = useReducer(
authenticationReducer,
initialState
) as any;
useEffect(() => {
let isSubscribed = true;
(async () => {
try {
console.log({ isSubscribed });
dispatch(setBusy(true));
const currentSession = await fakeApi();
const isAuthenticated = !!(currentSession && currentSession.isValid);
isSubscribed && dispatch(setIsAuthenticated(isAuthenticated));
} catch (err) {
console.error(err);
isSubscribed && dispatch(setIsAuthenticated(false));
}
})();
return () => {
isSubscribed = false;
};
}, [dispatch]);
return { busy, isAuthenticated };
};
我不得不破解一个isSubscribed
局部变量,在分发前我都检查了这些变量
isSubscribed && dispatch(setIsAuthenticated(isAuthenticated));
我必须从useEffect
返回,否则会收到此错误:
取消useEffect清理功能中的所有订阅和异步任务
该钩子的用法如下:
从“ react”导入React; 从“ react-router-dom”导入{重定向}; 从“ ./useIsUserAuthenticated”导入{useIsUserAuthenticated};
export interface AuthenticationContainerProps {
redirectTo: string;
}
export const AuthenticatedContainer: React.FC<AuthenticationContainerProps> = ({
children,
redirectTo
}) => {
const { busy, isAuthenticated } = useIsUserAuthenticated();
if (busy) {
return <h1>Busyyyyyy</h1>;
}
return isAuthenticated ? <>{children}</> : <Redirect to={redirectTo} />;
};
我真的不喜欢这种黑客手段,但是想不出更好的方法。
我创建了一个codesandbox来说明问题,但似乎并没有在codeandbox中发生,但在实际应用程序中确实发生了。
这看起来很糟糕,有更好的方法吗?