Сброс контекста из вспомогательной службы

#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]);

  // ...
}