ReactJS如何在app.js中使用withRouter

时间:2019-04-26 16:25:13

标签: reactjs react-router-dom

我需要使用withRouter,以便可以使用历史记录来在JWT过期且用户自动登录时重定向用户

我尝试导入withRouter,就像在其他组件中使用它一样,将export default AppwithRouter包裹在一起,如下所示:export default withRouter(App);

但这是我得到的错误:

Error: Invariant failed: You should not use Route outside a Router
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, withRouter } from 'react-router-dom';
import jwt_decode from 'jwt-decode';
import setAuthToken from './utils/setAuthToken';
import { setCurrentUser, logoutUser } from './actions/authActions';

import { Provider } from 'react-redux';
import store from './store';

import Navbar from './components/Navbar';
import UsersManagement from './components/UsersManagement';
import Login from './components/Login';
import AddUser from './components/users/AddUser';

import './App.css';

if (localStorage.jwtToken) {
  setAuthToken(localStorage.jwtToken);
  const decoded = jwt_decode(localStorage.jwtToken);
  store.dispatch(setCurrentUser(decoded));
  const currentTime = Date.now() / 1000;
  if (decoded.exp < currentTime) {
    store.dispatch(logoutUser(this.props.history));
    window.location.href = '/login';
  }
}

class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <Router>
          <div className="container">
            <Route exact path="/" component={Navbar} />
            <Route exact path="/" component={UsersManagement} />
            <Route exact path="/login" component={Login} />
            <Route exact path="/add-user" component={AddUser} />
          </div>
        </Router>
      </Provider>
    );
  }
}

export default withRouter(App);

如何解决此问题?

3 个答案:

答案 0 :(得分:1)

因此问题在于,您只能 withRouter用于<Router /> 子级的组件,并且由于App不是( <Router />的容器组件)会引发错误。

此外,此逻辑应在获取所需道具的某些组件内:

if (localStorage.jwtToken) {
  setAuthToken(localStorage.jwtToken);
  const decoded = jwt_decode(localStorage.jwtToken);
  store.dispatch(setCurrentUser(decoded));
  const currentTime = Date.now() / 1000;
  if (decoded.exp < currentTime) {
    store.dispatch(logoutUser(this.props.history));
    window.location.href = '/login';
  }
}

答案 1 :(得分:0)

如果您使用axios进行请求,则可以使用拦截器来验证响应,然后注销/重定向用户。

// Add a response interceptor
axios.interceptors.response.use(function (response) {
    // Do something with response data
    return response;
  }, function (error) {
    // Do something with response error
    return Promise.reject(error);
  });

答案 2 :(得分:0)

您可以在index.js中使用Router并为所有路由安装App

// In index.js
<Provider store={store}>
  <Router>
    <App />
  </Router>
</Provider>

// In App.js

class App extends Component {

  componentDidMount () {
    if (localStorage.jwtToken) {
      setAuthToken(localStorage.jwtToken);
      const decoded = jwt_decode(localStorage.jwtToken);
      store.dispatch(setCurrentUser(decoded));
      const currentTime = Date.now() / 1000;
      if (decoded.exp < currentTime) {
        store.dispatch(logoutUser(this.props.history));
        window.location.href = '/login';
      }
    }
  }
  
  render() {
    return (
        <>
          <Route exact path="/" component={Navbar} />
          <Route exact path="/" component={UsersManagement} />
          <Route exact path="/login" component={Login} />
          <Route exact path="/add-user" component={AddUser} />
        </>
    );
  }
}

export default withRouter(App);