Я пытаюсь создать функциональный компонент, эквивалентный следующему компоненту класса PrivateRoute (исходный код здесь ):
import React, { useState, useEffect } from "react";
import { Route, Redirect, withRouter, useHistory } from "react-router-dom";
import { Auth } from "aws-amplify";
class PrivateRoute extends React.Component {
state = {
loaded: false,
isAuthenticated: false
};
componentDidMount() {
this.authenticate();
this.unlisten = this.props.history.listen(() => {
Auth.currentAuthenticatedUser()
.then(user => console.log("user: ", user))
.catch(() => {
if (this.state.isAuthenticated)
this.setState({ isAuthenticated: false });
});
});
}
componentWillUnmount() {
this.unlisten();
}
authenticate() {
Auth.currentAuthenticatedUser()
.then(() => {
this.setState({ loaded: true, isAuthenticated: true });
})
.catch(() => this.props.history.push("/auth"));
}
render() {
const { component: Component, ...rest } = this.props;
const { loaded, isAuthenticated } = this.state;
if (!loaded) return null;
return (
<Route
{...rest}
render={props => {
return isAuthenticated ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: "/auth"
}}
/>
);
}}
/>
);
}
}
export default withRouter(PrivateRoute);
Приведенный выше код работает в моем приложении, когда я использую это так:
<PrivateRoute
exact
path={urls.homepage}
component={Homepage}
/>
Моя попытка преобразовать вышеуказанный компонент класса в функциональный компонент заключается в следующем:
import React, { useState, useEffect } from "react";
import { Route, Redirect, useHistory } from "react-router-dom";
import { Auth } from "aws-amplify";
const PrivateRoute = ({ component: Component, ...rest }) => {
const [isLoaded, setIsLoaded] = useState(false);
const [isAuthenticated, setIsAuthenticated] = useState(false);
let history = useHistory();
useEffect(() => {
Auth.currentAuthenticatedUser()
.then(() => {
setIsLoaded(true);
setIsAuthenticated(true);
})
.catch(() => history.push("/auth"));
return () =>
history.listen(() => {
Auth.currentAuthenticatedUser()
.then(user => console.log("user: ", user))
.catch(() => {
if (isAuthenticated) setIsAuthenticated(false);
});
});
}, [history, isAuthenticated]);
if (!isLoaded) return null;
return (
<Route
{...rest}
render={props => {
return isAuthenticated ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: "/auth"
}}
/>
);
}}
/>
);
};
export default PrivateRoute;
Но при использовании моего функционального компонента таким же образом, Я получаю следующее сообщение об ошибке:
Предупреждение. Не удается выполнить обновление состояния React для отключенного компонента. Это неоперация, но она указывает на утечку памяти в вашем приложении. Чтобы исправить, отмените все подписки и асинхронные задачи в функции очистки useEffect
Она всегда перенаправляет меня в / auth, независимо от того, вошел я в систему или нет. Что я делаю неправильно? Любая помощь очень ценится!