Как перенаправить на страницу входа после нажатия кнопки выхода из системы в заголовке панели навигации в React? - PullRequest
0 голосов
/ 04 апреля 2019

Я новичок в React. Я реагирую на конфигурацию маршрутизатора в App.js следующим образом:

<BrowserRouter>
    <div className="App">
      <Header />
      <Switch>
        <Route exact path="/" component={Home}>
        </Route>
        <Route exact path="/management" component={Management}>
        </Route>
        <Route exact path="/sign-up" component={SignUpForm}>
        </Route>
        <Route exact path="/sign-in" component={SignInForm}>
        </Route>
        <Route component={Error}>
        </Route>
      </Switch>
    </div>
  </BrowserRouter >

Я хочу, чтобы заголовок показывался на каждой странице, в заголовке есть кнопка выхода из системы, я хочу перенаправить на страницу входа в систему после нажатия на нее. В моем компоненте заголовка это выглядит так:

class Header extends Component {
constructor(props) {
    super(props);
    this.state = {
        redirect: false
    }

}
logout = () => {
    sessionStorage.setItem("userToken", '');
    sessionStorage.clear();
    this.setState({ redirect: true });


}
render() {
    if (this.state.redirect) {
        return (
            <Redirect to={'/sign-in'} />
        )
    }


    return (
        <div>

            <Navbar collapseOnSelect expand="md" bg="dark" variant="dark" fixed="top" >
               ......
                        <NavLink to="/management" className="header-link"><FontAwesomeIcon icon="cog" size="lg" /></NavLink>
                        <button type='button' onClick={this.logout}>Log Out</button>
                    </Nav>
                </Navbar.Collapse>
            </Navbar>
        </div>
    );
}
}
export default Header;

Там будут ошибки "Предупреждение. Вы попытались перенаправить на тот же маршрут, на котором находитесь в данный момент:" / вход в систему ", и навигационная панель пропадет только в теле входа в систему. Могу я узнать, что это правильный способ сделать это? Я также попытался this.props.history.push ('/ вход в систему), но нет props.history, вероятно, потому что заголовок не в маршруте? Должен ли я использовать с маршрутизатором? Или я должен на самом деле, просто сделайте каждый заголовок импорта страницы вместо этого поместите его в app.js? или какой на самом деле правильный способ сделать это? Большое спасибо за вашу помощь!

Ответы [ 3 ]

2 голосов
/ 04 апреля 2019

Компоненты, связанные с Маршрутами, получают доступ к историческому объекту в качестве реквизита, поэтому вы можете изменять его по мере необходимости, например, при выходе из системы. Поскольку ваш компонент Header не имеет доступа к объекту истории, вам придется использовать маршрутизатор более низкого уровня, чтобы предоставить ему доступ к объекту истории:

import { Router } from "react-router"
import { createBrowserHistory } from "history"

const history = createBrowserHistory()

<Router history={history}>
  <div className="App">
      <Header history={history} />
      <Switch>
        <Route exact path="/" component={Home}>
        </Route>
        <Route exact path="/management" component={Management}>
        </Route>
        <Route exact path="/sign-up" component={SignUpForm}>
        </Route>
        <Route exact path="/sign-in" component={SignInForm}>
        </Route>
        <Route component={Error}>
        </Route>
      </Switch>
    </div>
</Router>

теперь внутри вашего компонента заголовка вы можете позвонить history.push('/login')

см. Ссылку: https://reacttraining.com/react-router/web/api/Router/history-object

2 голосов
/ 04 апреля 2019

Вы можете реализовать вход / выход из системы с помощью маршрута, используя HOC, который проверяет элемент сеанса при каждом изменении маршрута. Если сеанс имеет userToken, то он будет перенаправлен на данный компонент, в противном случае будет перенаправлен на компонент входа в систему.

import React from "react"
import {Redirect} from "react-router-dom"

export const PrivateRoute = ({component: Component, ...rest}) => (
    <Route {...rest} render={(props) => (
        sessionStorage.getItem('userToken') ? <Component {...props} /> : <Redirect to="/sign-in"/>
    )} />
)

import <PrivateRoute> и используйте его в качестве авторизованного пути. И оставьте все остальные пути как обычные маршруты, по которым вам не нужна авторизация.

<BrowserRouter>
    <div className="App">
        <Header />
        <Switch>
            <PrivateRoute path="/" component={Home} />
            <PrivateRoute path="/management" component={Management} />
            <Route path="/sign-up" component={SignUpForm} />
            <Route path="/sign-in" component={SignInForm} />
            <Route component={Error} />
        </Switch>
    </div>
</BrowserRouter >

Поэтому, когда вы выйдете из системы, элемент сеанса будет удален и автоматически перенаправлен на страницу входа.

class Header extends Component {

....

logout = () => {
    sessionStorage.removeItem("userToken");
    sessionStorage.clear(); 
}

render() {
    return (
        <div>
          ...
          <button type='button' onClick={this.logout}>Log Out</button>
        </div>
    )
}
}
export default Header;
1 голос
/ 04 апреля 2019

Есть два подхода, которые вы упоминаете здесь.Вы можете использовать компонент высшего порядка 'withRouter' , который дает компонентам доступ к объекту истории.Используя объект history , который будет передан вашему компоненту в качестве реквизита, вы можете перейти к нужному маршруту.

Лично мне нравится настраивать ссылки выхода для визуализации компонента.он содержит логику выхода из системы и выполняет перенаправление на вход после его завершения.Таким образом, пользователи могут перейти непосредственно к ссылке выхода, если они хотят, и вы можете ссылаться на нее из любого места в вашем приложении по мере необходимости, без необходимости дублировать логику.

В маршрутизаторе браузера вы можетедобавьте путь для "/ logout", который визуализирует компонент, подобный этому (основываясь на вашей логике):

import React, { Component } from 'react';
import { Redirect } from 'react-router';

export default class LogOut extends Component {
    state = {
        redirect: false,
    };

    componentDidMount() {
        sessionStorage.setItem("userToken", '');
        sessionStorage.clear();
        this.setState({ redirect: true });
    }

    render() {
        return this.state.redirect ?
            <Redirect to={'/sign-in'} /> :
            null;
    }
}

Обычно я бы сделал ajax-запрос для очистки сеанса и затем установил быState после завершения, но вашвсе на стороне сервера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...