connected-react-router
connected-react-router copied to clipboard
Uncaught TypeError: Cannot read property 'push' of undefined!!!!
Hi,
I am a new user struggling with migrating from react-router to connected-react-router. I am receiving an error:
Uncaught TypeError: Cannot read property 'push' of undefined
when trying to redirect to another page. The redirect happens but I am receiving this error in the console.
Currently, my ErrorBoundary component is still using react-router and is initialised using withRouter. Not sure if that would cause the error??
Where am I incorrectly configuring connected-react-router or is this a bug?
Config is taking too long. I have now managed to get react-router working with withRouter and can access history, current path etc. that way....
Functional component
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import Grid from '@material-ui/core/Grid';
import { GridSpacing } from '@material-ui/core/Grid';
import Course from '../components/Course/Course';
import { courseModels } from '../redux/features/course';
import { courseSelectors } from '../redux/features/course';
import { fetchCoursesAsync } from '../redux/features/course/actions';
import { RootState } from 'ReduxTypes';
import { push } from 'connected-react-router';
type ErrorReport = { hasError: boolean; error?: Error };
type StateProps = {
isLoading: boolean;
courses: courseModels.Course[];
error: ErrorReport;
};
/**
* Redux dispatch and state mappings
*/
const dispatchProps = {
fetchCourses: fetchCoursesAsync.request,
history: { push },
};
const mapStateToProps = (state: RootState): StateProps => ({
isLoading: state.courses.isLoadingCourses,
courses: courseSelectors.getReduxCourses(state.courses),
error: courseSelectors.getReduxCoursesError(state.courses),
});
/**
* Component property type definitions
*/
type Props = ReturnType<typeof mapStateToProps> & typeof dispatchProps;
/**
* CourseList component
*/
const CourseList = ({
courses = [],
error,
fetchCourses,
history,
isLoading,
}: Props): JSX.Element => {
// fetch course action on mount
useEffect(() => {
console.log('COURSELIST FETCHING COURSES');
fetchCourses();
}, [fetchCourses]);
if (isLoading) {
return <p>Loading...</p>;
}
// THIS IS CAUSING THE ERROR, REDIRECT HAPPENS BUT ERROR MESSAGE IS
// DISPLAYED IN CONSOLE
history.push('/error');
return (
<div style={{ marginTop: 20, padding: 30 }}>
{
<Grid container spacing={2 as GridSpacing} justify="center">
{courses.map(element => (
<Grid item key={element.courseID}>
<Course course={element} />
</Grid>
))}
</Grid>
}
</div>
);
};
/**
* Exports
*/
export default connect(
mapStateToProps,
dispatchProps,
)(CourseList);
index.ts for store module
import { RootAction, RootState } from 'ReduxTypes';
import { createStore, applyMiddleware } from 'redux';
import { createEpicMiddleware } from 'redux-observable';
import { createBrowserHistory } from 'history';
import { routerMiddleware as createRouterMiddleware } from 'connected-react-router';
import { composeEnhancers } from './utils';
import rootReducer from './rootReducer';
import rootEpic from './rootEpic';
import services from '../../services';
// browser history
export const history = createBrowserHistory();
export const epicMiddleware = createEpicMiddleware<
RootAction,
RootAction,
RootState
>({
dependencies: services,
});
const routerMiddleware = createRouterMiddleware(history);
// configure middlewares
const middlewares = [epicMiddleware, routerMiddleware];
// compose enhancers
const enhancer = composeEnhancers(applyMiddleware(...middlewares));
// rehydrate state on app start
const initialState = {};
// create store
const store = createStore(rootReducer(history), initialState, enhancer);
epicMiddleware.run(rootEpic);
// export store singleton instance
export default store;
Routing component
import React, { Component, Suspense, lazy } from 'react';
import { Route, Switch } from 'react-router';
import { history } from '../redux/store';
import ErrorPage from '../errors/ErrorPage';
import ErrorBoundary from '../errors/ErrorBoundary';
import { NavBar } from './NavBar/NavBar';
import { ConnectedRouter } from 'connected-react-router';
// lazy loading components and other stuff here, skipping ahead....
type AppProps = {};
export class App extends Component<AppProps, {}> {
public render(): JSX.Element {
return (
<ConnectedRouter history={history}>
<div>
<NavBar />
<Suspense fallback={<div>LoaderOptionsPlugin...</div>}>
<Switch>
<Route path="/" component={Home} exact></Route>
<Route path="/about" component={About}></Route>
<Route
path="/courses"
render={(props): JSX.Element => (
<ErrorBoundary {...props}>
<CourseList {...this.props} />
</ErrorBoundary>
)}
></Route>
<Route path="/error" component={ErrorPage}></Route>
{/* <Route component={Error404}></Route> */}
</Switch>
</Suspense>
</div>
</ConnectedRouter>
);
}
}
Root reducer
import { combineReducers } from 'redux';
import { History } from 'history';
import coursesReducer from '../features/course/reducer';
import { connectRouter } from 'connected-react-router';
const rootReducer = (history: History) =>
combineReducers({
router: connectRouter(history),
courses: coursesReducer,
});
export default rootReducer;
Dependencies
"dependencies": {
...
"connected-react-router": "6.5.2",
"react": "16.10.1",
"react-dom": "16.10.1",
"react-redux": "7.1.1",
"react-router": "5.1.2",
"react-router-dom": "5.1.2",
"redux": "4.0.4",
"redux-observable": "1.2.0",
...
}
I think, you should import {withRouter{ from react router
try this myabe you find it helpful
import { withRouter } from 'react-router';
class yourClassNAme extends Component { ... }
export default withRouter(yourClassNAme );
I think, you should import {withRouter{ from react router try this myabe you find it helpful
import { withRouter } from 'react-router';
class yourClassNAme extends Component { ... }
export default withRouter(yourClassNAme );
I'm having a similar issue, but when I'm trying to do that on my App.js, I get: Error: Invariant failed: You should not use <withRouter(App) /> outside a <Router>
I think, you should import {withRouter{ from react router try this myabe you find it helpful import { withRouter } from 'react-router'; class yourClassNAme extends Component { ... } export default withRouter(yourClassNAme );
I'm having a similar issue, but when I'm trying to do that on my App.js, I get:
Error: Invariant failed: You should not use <withRouter(App) /> outside a <Router>
Found any solution? I'm having exact same issue