Я использую React с Firebase для разработки небольшого веб-приложения. Чтобы позаботиться об аутентификации, я использую контекстный API, а внутри контекста добавляю данные пользователя, вошедшего в систему.
AuthProvider.tsx
const AuthProvider: React.FC = props => {
const [state, setState] = useState<IAuthContext>(authInitialState);
console.log("Inside AuthProvider");
useEffect(() => {
auth.onAuthStateChanged( user => {
console.log("Auth State changed and user is ----->", user);
if (user) {
console.log("User value updated to the context")
setState({
...authInitialState,
isAuthenticated:!!user,
permissions:[],
user:user
});
}
const stateChange = {
...authInitialState,
isAuthenticated: !!user,
user
};
// if (!user) {
return setState(stateChange);
// }
});
}, []);
console.log("Rendering AuthProvider", state);
return (
<AuthContext.Provider value={state}>{props.children}</AuthContext.Provider>
);
};
export default AuthProvider;
AuthConsumer. tsx
const withAuthContext = (
Component: React.ComponentClass<any> | React.FunctionComponent<any>
) => {
console.log("Rendering AuthConsumer for ");
return (props: any) => (
<AuthContext.Consumer>
{context => <Component {...props} context={context} />}
</AuthContext.Consumer>
);
};
export default withAuthContext;
PrivateRoute.tsx
interface PrivateRouteProps extends RouteProps {
// tslint:disable-next-line:no-any
component: any;
context: IAuthContext;
}
const PrivateRoute = (props: PrivateRouteProps) => {
const { component: Component, context: IAuthContext, ...rest } = props;
console.log("Private route for ", props);
return (
<Route
{...rest}
render={(routeProps) =>
props.context.isAuthenticated ? (
<Component {...routeProps} />
) : (
<Redirect
to={{
pathname: '/login',
state: { from: routeProps.location }
}}
/>
)
}
/>
);
};
export default withAuthContext(PrivateRoute);
App.tsx
return (
<BrowserRouter>
<div>
<Switch>
<PublicRoute path="/frame" component={Frame} exact isAuthorized={true}/>
<Route path="/login" component={NewLogin} exact isAuthorized={true}/>
<PrivateRoute path="/nav" component={NavigationBar} exact/>
<PrivateRoute path="/dashboard" component={AnalyticsDashBoard} exact/>
<PrivateRoute path="/subscription" component={OrderSuccess} exact/>
<PrivateRoute path="/onboarding" component={OnBoarding} exact/>
</Switch>
</div>
</BrowserRouter>
);
пользователь уже вошел в систему, а постоянство сеанса установлено на локальное. Проблема в том, что когда я пытаюсь использовать localhost / subscription, который является частным маршрутом, context.isAuthenticated имеет значение false, поскольку наблюдатель «onAuthStateChanged» еще не запущен, поэтому он собирается перейти на страницу входа, но через несколько миллисекунд, authStateChange сработал и контекст установился, но это бесполезно, так как приложение уже перешло к входу в систему, так как privateroute думал, что пользователь не залогинен Я хотел бы получить знания о том, как преодолеть эту проблему.