#javascript #reactjs #react-hooks
#javascript #reactjs #react-перехваты
Вопрос:
Я пытаюсь аутентифицировать пользователя при каждом изменении маршрута с помощью react-router-dom
и react hooks
. Идея заключается в том, что каждый раз, когда пользователь переходит к маршруту, система выполняет вызов api и аутентифицирует пользователя. Мне нужно добиться этого, потому что я использую react-redux
, и при каждой перезагрузке окна состояние redux не сохраняется. Итак, мне нужно снова установить для isLoggedNow
prop значение true
:
const PrivateRoute = ({
component: Component,
checkOnEachRoute: checkReq,
isUserLogged,
...rest
}) => {
const [isLoggedNow, setLogged] = useState(isUserLogged);
useEffect(
() => {
const fetchStatus = async () => {
try {
await selectisUserLogged();
setLogged(true);
} catch (error) {
console.log(error);
}
};
fetchStatus();
},
[isUserLogged],
);
return (
<Route
{...rest}
render={props =>
isLoggedNow ? (
<div>
<Component {...props} />
</div>
) : (
<Redirect
to={{
pathname: '/login',
}}
/>
)
}
/>
);
};
Затем я бы использовал вышеуказанное PrivateRoute
следующим образом:
function App(props) {
return (
<div>
<Switch location={props.location}>
<Route exact path="/login" component={Login} />
<PrivateRoute exact path="/sidebar" component={Sidebar} />
</Switch>
</div>
);
}
Сначала isUserLogged
есть true
, но после перезагрузки окна я получаю сообщение об ошибке Warning: Can't perform a React state update on an unmounted component.
Итак, как я могу добиться этого, чтобы при каждой перезагрузке окна я аутентифицировал пользователя? Я ищу какой-то componentWillMount
.
Комментарии:
1. у вас была возможность решить эту проблему?
2. @camelCase да!
3. хотите поделиться? 🙂 на данный момент сталкиваюсь с точно такой же проблемой
4. @camelCase Смотрите мой ответ, это решает проблему для вас?:)
Ответ №1:
Что-то вроде этого работает (где isUserLogged
это реквизит из redux):
function PrivateRoute({ component: Component, isUserLogged, ...rest }) {
const [isLoading, setLoading] = useState(true);
const [isAuthenticated, setAuth] = useState(false);
useEffect(() => {
const fetchLogged = async () => {
try {
setLoading(true);
const url = new URL(fetchUrl);
const fetchedUrl = await fetchApi(url);
setAuth(fetchedUrl.body.isAllowed);
setLoading(false);
} catch (error) {
setLoading(false);
}
};
fetchLogged();
}, []);
return (
<Route
{...rest}
render={props =>
// eslint-disable-next-line no-nested-ternary
isUserLogged || isAuthenticated ? (
<Component {...props} />
) : isLoading ? (
<Spin size="large" />
) : (
<Redirect
to={{
pathname: '/login',
}}
/>
)
}
/>
);
}
Комментарии:
1. Кажется, у меня тоже работает, просто есть вопрос, почему у вас isUserLogged передан в props?
2. @camelCase У меня была идея
fetchLogged();
включитьìf(!isUserLogged)...
, поэтому извлекать только в том случае, если не isUserLogged 🙂