Tom
Tom

Reputation: 4652

Cannot pass down history prop to Component

I want to pass down the history prop down from the App to the Navigation component. When I try to do so, I get the following error message:

Failed prop type: The prop history is marked as required in Navigation, but its value is undefined.

How can I resolve this issue?

App.js:

import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';

const App = props => (
  <Router>
      <MainLayout {...props}>
        <Switch>
          <Route exact name="index" path="/" component={Index}/>
          <Route component={NotFound}/>
        </Switch>
      </MainLayout>
  </Router>
);

MainLayout.js:

import React from "react";
import PropTypes from "prop-types";
import Navigation from "../../components/Navigation/Navigation";

const MainLayout = props => {
  const { children, authenticated, history } = props;

  return (
    <div>
      <Navigation authenticated={authenticated} history={history} />
      {children}
    </div>
  );
};

MainLayout.PropTypes = {
  children: PropTypes.node.isRequired,
  authenticated: PropTypes.bool.isRequired,
  history: PropTypes.object.isRequired,
};

export default MainLayout;

Upvotes: 3

Views: 4435

Answers (2)

Maxwelll
Maxwelll

Reputation: 2212

SOLUTION #1:

If you simply convert <MainLayout /> to a <Route /> that renders you will have access to the history object.

<Route render={(props) => 
  <MainLayout {...props}>
    <Switch>
      <Route exact name="index" path="/" component={Index}/>
      <Route component={NotFound}/>
    </Switch>
  </MainLayout>
}/>

https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/Route.js

<App /> does not have access to history as a prop so this will never do what you are wanting <MainLayout {...props}>

SOLUTION #2

You can also reference the history object as a single exported module in your app and refer to that both React router and any other compopent / javascript file in your app.

import { Router, Switch, Route } from 'react-router-dom';
import history from './history';

const App = props => (
  <Router history={history}>
      <MainLayout history={history} {...props}>
        <Switch>
          <Route exact name="index" path="/" component={Index}/>
          <Route component={NotFound}/>
        </Switch>
      </MainLayout>
  </Router>
);

(history.js)

import createBrowserHistory from 'history/createBrowserHistory';

export default createBrowserHistory();

https://www.npmjs.com/package/history

Upvotes: 5

MeanMan
MeanMan

Reputation: 1090

For react-router-dom v4

In order to get Router component's prop I used the withRouter, I guess the below change should work,

export default wihtRouter(MainLayout);

This should enable the usage of props.history in MainLayout

Upvotes: 4

Related Questions