K
K
Ken Jee2019-06-11 11:25:18
React
Ken Jee, 2019-06-11 11:25:18

How to fix history of undefined error when using BrowserRouter from react-router-dom version 5 module?

Why is there an error when using BrowserRouter from react-router-dom version 5

Uncaught TypeError: Cannot read property 'history' of undefined

import "../../styles/scss/app.scss";

import React from 'react';

import { BrowserRouter, Route, Switch } from 'react-router-dom';
import PrivateRoute from 'react-private-route';

import Login from './Login';
import Home from './Home';
import NotFound from "./NotFound";

export default class App extends React.Component {

    render() {

        return(
            <BrowserRouter>
                <Switch>
                    <Route path="/login" component={Login} />
                    <PrivateRoute exact path="/" component={Home} isAuthenticated={true} />
                    <Route component={NotFound} />
                </Switch>
            </BrowserRouter>
        )

    }

}

import React, {Suspense} from "react";
import ReactDOM from "react-dom";
import { I18nextProvider } from 'react-i18next';
import i18n from './i18n';

import App from "./components/App";

ReactDOM.render(
    <I18nextProvider i18n={i18n}>
        <Suspense fallback="Loading">
            <App />
        </Suspense>
    </I18nextProvider>,
    document.getElementById('root')
);

5cff64f329a50703054651.png
UPD:
Everything works fine if PrivateRoute is replaced in App.js with a regular Route... The problem is clearly related to PrivateRoute from the react-private-route module https://github.com/hansfpc/react-private-route

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Spirin, 2019-06-11
@Machez

Cut out react-private-route. This library uses the previous version of react-router.
The component you need can be implemented like this:

const PrivateRoute = ({ component: Component, render, isSignedIn, ...rest }) => (
  <Route
    {...rest}
    render={props => {
      if (!isSignedIn) return (
        <Redirect
          to={{
            pathname: '/login',
            state: { referrer: props.history.location.pathname },
          }}
        />
      );

      if (render) return render({ ...props });

      return <Component {...props} />;
    }}
  />
);

If you are using Redux, then you can add a wrapper:
const mapStateToProps = (state) => ({
  isSignedIn: isSignedInSelector(state),
});

export default connect(mapStateToProps)(PrivateRoute);

and don't pass isSignedIn in hardcode. Context can also be used for this purpose.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question