#reactjs
#reactjs
Вопрос:
Я создал класс сервиса, который я использую для обработки аутентификации в моем приложении React. Данные о текущем вошедшем в систему пользователе хранятся в контексте пользователя. Когда пользователь нажимает кнопку выхода из системы, logout()
вызывается служба аутентификации. Пользовательский контекст затем может быть сброшен в том же событии щелчка с помощью this.context.updateUser()
.
Но бывают случаи, когда пользователю необходимо выйти из системы, даже если он не нажимал кнопку выхода, например, если их сеанс недействителен. В этом случае forceLogout()
будет вызываться изнутри службы аутентификации. Однако, поскольку это не происходит внутри компонента, это не оставляет мне возможности сбросить пользовательский контекст. Текущий код выдает ошибку: Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
.
Как я могу сбросить пользовательский контекст изнутри forceLogout()
?
// user.context.js
import React, { createContext, Component } from 'react';
import AuthService from '../services/auth.service';
export const UserContext = createContext();
class Context extends Component {
state = {
user: AuthService.getCurrentUser(),
updateUser: (user) => {
this.setState({ user });
}
};
render() {
return (
<UserContext.Provider value={this.state}>
{this.props.children}
</UserContext.Provider>
);
}
}
export default Context;
// auth.service.js
import { useContext } from 'react';
import { UserContext } from '../contexts/user.context';
import history from '../history';
Class AuthService {
getCurrentUser() {
return JSON.parse(localStorage.getItem('user'));
}
logout() {
localStorage.removeItem('user');
}
forceLogout() {
const userContext = useContext(UserContext);
localStorage.removeItem('user');
userContext.updateUser();
history.push('/');
}
...
}
Комментарии:
1. Вы можете использовать
hooks
только в функциональном компоненте
Ответ №1:
Создайте Logout
компонент, который будет общим для всех типов выхода из системы, и примените свою логику выхода из системы внутри componentDidMount
или внутри useEffect
Logout
компонента, поскольку это компонент, который вы можете использовать здесь, и всякий раз, когда вы хотите выйти из системы, просто перенаправляйте на компонент выхода из системы, и если вы хотите перенаправить обратно на домашнюю страницу после выхода из системы, выполнитеэто внутренний компонент выхода из системы.
Ответ №2:
Вы можете использовать пользовательские события:
Class AuthService {
// ...
forceLogout() {
localStorage.removeItem('user');
// Dispatch logout event.
const event = new Event('force-logout');
window.dispatchEvent(event);
}
}
Затем внутри компонента под UserContext.Provider
:
const SomeComponent = () => {
const userContext = useContext(UserContext);
useEffect(() => {
const handleLogout = () => {
userContext.updateUser();
history.push('/');
};
window.addEventListener('force-logout', handleLogout);
return () => window.removeEventListener('force-logout', handleLogout);
}, [userContext, history]);
// ...
}