Machez
@Machez
Бу!

Как исправить ошибку history of undefined при использовании BrowserRouter из модуля react-router-dom версии 5?

Почему при использовании BrowserRouter изreact-router-dom версии 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:
Все работает нормально, если в App.js PrivateRoute заменить на обычный Route... Проблемка явно связана с PrivateRoute из модуля react-private-route https://github.com/hansfpc/react-private-route
  • Вопрос задан
  • 1171 просмотр
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
Выпиливайте react-private-route. Эта библиотека использует предыдущую версию react-router.
Нужный вам компонент можно реализовать так:
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} />;
    }}
  />
);


Если используете Redux, то можно добавить обертку:
const mapStateToProps = (state) => ({
  isSignedIn: isSignedInSelector(state),
});

export default connect(mapStateToProps)(PrivateRoute);

и не передавать isSignedIn хардкодом. Так же для этой цели можно использовать контекст.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы