346

I have the following structure for my React.js application using React Router:

var Dashboard = require('./Dashboard');
var Comments = require('./Comments');

var Index = React.createClass({
  render: function () {
    return (
        <div>
            <header>Some header</header>
            <RouteHandler />
        </div>
    );
  }
});

var routes = (
  <Route path="/" handler={Index}>
    <Route path="comments" handler={Comments}/>
    <DefaultRoute handler={Dashboard}/>
  </Route>
);

ReactRouter.run(routes, function (Handler) {
  React.render(<Handler/>, document.body);
});

I want to pass some properties into the Comments component.

(normally I'd do this like <Comments myprop="value" />)

What's the easiest and right way to do so with React Router?

icc97
  • 8,746
  • 6
  • 60
  • 75
Kosmetika
  • 19,249
  • 37
  • 94
  • 154
  • The problem here, and in such similar cases, especially with the frameworks or libs written in some langs, a certain lack of **means of combination** (MoC). **Primitives** seems ok in React they are pretty good, defining components with primitives, in React elements and the component, **MoC**, which seems ok as well in React. But **means of combination** is incomplete. One must be able to *pass the props to a component* while combining a component to another, doesn't matter if by putting one component inside another component as a child of it or passing one component as a props to another. – sçuçu Mar 03 '17 at 10:57
  • With some syntax like `} />} />` OR `` Otherwise, this **problems of combinations of abstractions** will recur and will need some less than optimal and indirect solutions called workarounds like wrapping etc, etc. Abstractions must be first class citizens as primitives, whatever the first class perception means. – sçuçu Mar 03 '17 at 10:59

25 Answers25

263

If you'd rather not write wrappers, I guess you could do this:

class Index extends React.Component { 

  constructor(props) {
    super(props);
  }
  render() {
    return (
      <h1>
        Index - {this.props.route.foo}
      </h1>
    );
  }
}

var routes = (
  <Route path="/" foo="bar" component={Index}/>
);
Thomas E
  • 3,684
  • 2
  • 18
  • 13
  • 11
    This is a correct answer. In the react-router 1.0, you can get `route` plain object in your component. Here's the answer of github issue: https://github.com/rackt/react-router/issues/615#issuecomment-100432086 – ycdesu Sep 26 '15 at 03:25
  • 4
    This is the simple answer I was looking for. The other techniques work, but require 10x the amount of code. Works well for v1.0.x. The only downside I can see is if you intend to use the same component both with and without the router container. But for me, all my top-level components mapped 1-to-1 with routes. – killthrush Jan 04 '16 at 14:14
  • 12
    Great, thanks! If anyone is wondering, the foo property would be available in your component as: this.props.route.foo – k00k Jan 08 '16 at 17:12
  • I am doing a redirect as- `browserHistory.push('/new-route');` and I want to pass props to it. In my routes I have- `` How can this be done? – Chirag Mongia Mar 29 '16 at 07:38
  • From react-router docs v2.0: ```someHandler() { this.context.router.push(,,) }``` – Thomas E Mar 29 '16 at 18:23
  • But history.state won't be automatically transferred to props afaik, so you'd have to call that manually. I.e. ```history.state.object```, when entering component. – Thomas E Mar 29 '16 at 18:34
  • Humm, you couple your Index component to the router. Wrapper is better. – CpILL Mar 30 '16 at 05:36
  • 8
    Can this one be set as a correct answer to avoid the confusion? – Archibald Apr 08 '16 at 20:49
  • 1
    what's with the `Index -{this.props.route.foo}` syntax? or is that pseudocode? – taylorstine Jul 10 '16 at 17:48
  • Worked well for me, but I had to use: `this.props.route.options.foo` – Thilo Savage Jul 22 '16 at 12:11
  • 2
    Nope! See Rajesh Naroth answer for the real solution :) – Alex Aug 27 '16 at 03:24
  • 1
    @Archibald - component wrapping is also a good solution. It is even cleaner because the component there doesn't need to know about any router (`route.foo` property) and you can use any property name. – Martin Ždila Oct 18 '16 at 11:47
  • For some reason, if the component is a redux container, the property doesn't get propagated. It works with @Rajesh solution, taking into account the comment from yuji – Daniel Reina Apr 08 '17 at 19:28
  • 1
    **this.props.route** does not exist as v4. See [this](http://stackoverflow.com/a/43299633/253576) response below for an answer that worked for me. The code he uses is documented [here](https://github.com/ReactTraining/react-router/issues/4627) and [here](https://github.com/ReactTraining/react-router/commit/45649fd3cc6fbe4c5b89c3d0506f8f076c3fa6ed#commitcomment-20902957). – ccalvert Apr 30 '17 at 21:55
  • 1
    we need this answer further up, other answers are fairly outdated – Arijoon Nov 20 '17 at 12:17
177

UPDATE

Since new release, it's possible to pass props directly via the Route component, without using a Wrapper. For example, by using render prop.

Component:

class Greeting extends React.Component {
  render() {
    const {text, match: {params}} = this.props;

    const {name} = params;

    return (
      <React.Fragment>
        <h1>Greeting page</h1>
        <p>
          {text} {name}
        </p>
      </React.Fragment>
    );
  }
}

Usage:

<Route path="/greeting/:name" render={(props) => <Greeting text="Hello, " {...props} />} />

Codesandbox Example


OLD VERSION

My preferred way is wrap the Comments component and pass the wrapper as a route handler.

This is your example with changes applied:

var Dashboard = require('./Dashboard');
var Comments = require('./Comments');

var CommentsWrapper = React.createClass({
  render: function () {
    return (
      <Comments myprop="myvalue"/>
    );
  }
});

var Index = React.createClass({
  render: function () {
    return (
      <div>
        <header>Some header</header>
        <RouteHandler/>
      </div>
    );
  }
});

var routes = (
  <Route path="/" handler={Index}>
    <Route path="comments" handler={CommentsWrapper}/>
    <DefaultRoute handler={Dashboard}/>
  </Route>
);

ReactRouter.run(routes, function (Handler) {
  React.render(<Handler/>, document.body);
});
daaawx
  • 2,268
  • 2
  • 12
  • 13
ColCh
  • 2,643
  • 2
  • 18
  • 17
  • 58
    I'm running into the same problem, but doesn't this solution get verbose quickly? – captDaylight Mar 05 '15 at 23:17
  • 8
    Agree with captDaylight, it becomes verbose. Would prefer a better way to handle this! – Mattias Hallström Mar 11 '15 at 08:31
  • You can create decorator for this thing wrapping class creation into a function. – ColCh Sep 10 '15 at 10:07
  • 6
    @mattiashallstrom IMO, the better way in 1.0 is to simply add the property to the route. See Thomas E's answer. – k00k Jan 08 '16 at 17:20
  • 28
    you could add a stateless component syntax (just lambda) there also, it's pretty short ` ()}/>` – Ciantic Jun 17 '16 at 19:55
  • 33
    I will never agree with creating additional component just to pass properties being the "preferred way". It's verbose, complicated, error prone and just plainly wrong in every way imaginable. It might be the ONLY way react router allows, but calling it "preferred" is a stretch. Preferred by who? – Szczepan Hołyszewski Jun 29 '16 at 15:25
  • My library [React Router9](https://github.com/mik-jozef/react-router9) supports this using `` – Jozef Mikušinec Feb 14 '17 at 09:45
  • @JozefMikusinec yes, my solution was a temporary workaround for old react-router release. For current version my solution is outdated – ColCh Feb 15 '17 at 08:56
  • @Ciantic you should use `render` instead of `component` see [@dgrcode's answer](https://stackoverflow.com/a/43299633/327074) – icc97 May 27 '17 at 21:35
  • You should add a complete example for the updated method. – Harry Moreno Mar 27 '18 at 16:35
  • I like your answer because it helped my fingers to code some better. – Aid19801 Jan 13 '19 at 07:23
  • I keep getting `undefined` in the received component – Si8 Jul 09 '19 at 19:29
  • Any way to do this without using JSX? () - I have a routes file that is used to generate nav and then uses a to display. – Barry Chapman Nov 28 '20 at 04:48
120

Copying from the comments by ciantic in the accepted response:

<Route path="comments" component={() => (<Comments myProp="value" />)}/>

This is the most graceful solution in my opinion. It works. Helped me.

Community
  • 1
  • 1
Rajesh Naroth
  • 1,217
  • 1
  • 6
  • 2
  • This is basically the same as the wrapper answer above, but it's much less wordy. Man, though, that syntax sucks. Try throwing in a `_ref` – EdH Oct 03 '16 at 17:34
  • 11
    It's like a anonymous wrapper, so all injected props (eg. location) are missed. One has to manually pass props like `component={(props) => ()}` but it all gets messy again – yuji Oct 17 '16 at 11:01
  • Keep in mind, that for performance reasons lambda functions in JSX should be avoided. Granted, if it's necessary, it's necessary. – Jacob Thomason Nov 06 '16 at 01:22
  • 1
    @JacobThomason we don't re-render react router config so it's unlikely to be a performance penalty. – Sebastien Lorber Dec 07 '16 at 14:21
  • This answer and @cachvico are the best depending on your situation. For me this was perfect for dynamically created pages based on a prop. – Michael Hobbs Jan 02 '17 at 13:09
  • 9
    As of React-Router 4, if you provide an inline function you will get a lot of undesired remounting. For inline rendering, use the render prop. [Link to the docs](https://reacttraining.com/react-router/web/api/Route/component) – Daniel Reina Apr 08 '17 at 19:26
  • Do not forget to pass ownProps to map functions of connect() if you are a redux user. – Den Roman May 14 '17 at 17:50
  • 1
    @yuji To not make it too messy one can do: `component={(props) => ()}` to maintain the injected props – apelsinapa Aug 16 '17 at 12:26
60

This is the solution from Rajesh, without the inconvenient commented by yuji, and updated for React Router 4.

The code would be like this:

<Route path="comments" render={(props) => <Comments myProp="value" {...props}/>}/>

Note that I use render instead of component. The reason is to avoid undesired remounting. I also pass the props to that method, and I use the same props on the Comments component with the object spread operator (ES7 proposal).

Daniel Reina
  • 4,144
  • 31
  • 37
44

Just a follow-up to ColCh's answer. It is quite easy to abstract the wrapping of a component:

var React = require('react');

var wrapComponent = function(Component, props) {
  return React.createClass({
    render: function() {
      return React.createElement(Component, props);
    }
  });
};

<Route path="comments" handler={wrapComponent(Comments, {myprop: value})}/>

I haven't tested this solution yet so any feedback is important.

It's important to note that with this method, any props sent via the Router (such as params) get overwritten / removed.

Community
  • 1
  • 1
sigmus
  • 2,079
  • 2
  • 21
  • 28
  • I don't quite understand; how is "value" passed to the router? – Jane Panda Jun 05 '15 at 02:59
  • 1
    Bob, are you familiar with closures? http://stackoverflow.com/questions/111102/how-do-javascript-closures-work – sigmus Jun 05 '15 at 15:50
  • 3
    And if you need the query and params from the router as well, then something like this will work: `return React.createElement(Component, _.assign({}, this.props, props));` (This one uses _.assign to compose the combined object... other methods are available of course). – Malcolm Dwyer Sep 01 '15 at 21:33
  • 2
    You might want to pass the children also.| var wrapComponent = function(Component, props) { return React.createClass({ render: function() { return React.createElement(Component, props, this.props.children); } }); }; – Julio Rodrigues Sep 13 '15 at 01:13
  • Right, should pass children for warpComp when create new element. – Zack Yang Oct 10 '15 at 07:43
  • 1
    This is a Higher Order Component for those who aren't familiar with them https://facebook.github.io/react/docs/higher-order-components.html – icc97 May 27 '17 at 19:13
  • 1
    N.B. This is for an old version of React Router now. Current v4 has `render`, `component` and `children` methods for `Route`. Note that as [@dgrcode answer](https://stackoverflow.com/a/43299633/327074) points out, you should use `render` instead of `component` – icc97 May 27 '17 at 20:39
31

You can pass props by passing them to <RouteHandler> (in v0.13.x) or the Route component itself in v1.0;

// v0.13.x
<RouteHandler/>
<RouteHandler someExtraProp={something}/>

// v1.0
{this.props.children}
{React.cloneElement(this.props.children, {someExtraProp: something })}

(from the upgrade guide at https://github.com/rackt/react-router/releases/tag/v1.0.0)

All child handlers will receive the same set of props - this may be useful or not depending on the circumstance.

cachvico
  • 1,087
  • 12
  • 21
  • 1
    It really puzzles to see `React.cloneElement` being passed multiple elements but the [function signature](https://facebook.github.io/react/docs/top-level-api.html#react.cloneelement) seems to take only one react element. I think this snippet can be made easier to understand. – manu Oct 10 '15 at 19:38
  • 2
    This is clearly the best answer on target with the docs, but I also agree with manu that it could be written to show use better. Code more specific to the question would look like: `React.cloneElement(this.props.children, {myprop: "value"})` or `React.cloneElement(this.props.children, {myprop: this.props.myprop})` etc. – juanitogan Feb 26 '16 at 22:24
  • This answer wins. It is also a lot more clear what's going on in the midst of the stuff Router does for you. As someone reading the code, if I know Comments is inside Index, I'll look at Index to see what props are sent to Comments. If I happen to know that Comments is a router handler, I'll look at the router config and find out that Index parents comments and still go look there. – mejdev Mar 28 '16 at 20:53
24

Using ES6 you can just make component wrappers inline:

<Route path="/" component={() => <App myProp={someValue}/>} >

If you need to pass children:

<Route path="/" component={(props) => <App myProp={someValue}>{props.children}</App>} >

Nick
  • 8,946
  • 6
  • 35
  • 40
23

React-router v4 alpha

now there is a new way, to do this, although very similar to the previous method.

import { Match, Link, Miss } from 'react-router';
import Homepage from './containers/Homepage';

const route = {
    exactly: true,
    pattern: '/',
    title: `${siteTitle} - homepage`,
    component: Homepage
  }

<Match { ...route } render={(props) => <route.component {...props} />} />

P.S. This works only in alpha version, and were removed after the v4 alpha release. In v4 latest, is once again , with the path and exact props.

react-lego an example app contains code that does exactly this in routes.js on its react-router-4 branch

Taras Yaremkiv
  • 3,205
  • 6
  • 25
  • 48
peter.mouland
  • 1,288
  • 11
  • 28
21

Here's the cleanest solution I've come up with (React Router v4):

<Route
  path="/"
  component={props => <MyComponent {...props} foo="lol" />}
/>

MyComponent still has props.match and props.location, and has props.foo === "lol".

cgenco
  • 2,347
  • 2
  • 24
  • 28
12

Wrap it with a stateless function component:

<Router>
  <Route 
    path='/' 
    component={({children}) => 
      <MyComponent myProp={'myVal'}>{children}</MyComponent/>
    }/>
</Router>
Rafa
  • 8,431
  • 4
  • 35
  • 58
mg74
  • 371
  • 1
  • 3
  • 10
11

You could also use the RouteHandler mixin to avoid the wrapper component and more easily pass down the parent's state as props:

var Dashboard = require('./Dashboard');
var Comments = require('./Comments');
var RouteHandler = require('react-router/modules/mixins/RouteHandler');

var Index = React.createClass({
      mixins: [RouteHandler],
      render: function () {
        var handler = this.getRouteHandler({ myProp: 'value'});
        return (
            <div>
                <header>Some header</header>
                {handler}
           </div>
        );
  }
});

var routes = (
  <Route path="/" handler={Index}>
    <Route path="comments" handler={Comments}/>
    <DefaultRoute handler={Dashboard}/>
  </Route>
);

ReactRouter.run(routes, function (Handler) {
  React.render(<Handler/>, document.body);
});
jul
  • 974
  • 1
  • 10
  • 23
  • 1
    It's publicly exposed on the global bower build as ReactRouter.RouteHandlerMixin so I don't think so. – jul Jan 28 '15 at 16:37
  • This also allows for animating transitions using TransitionGroup and CSSTransitionGroup which I couldn't get to work using the wrapper method. – jul Jan 28 '15 at 16:41
  • 2
    It's strange that there's no mention about that in official docs. – Kosmetika Jan 28 '15 at 18:34
  • Mixins are no longer recommended by the React docs: https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html – icc97 May 27 '17 at 19:16
11

You can pass in props via the <RouterHandler/> like this:

var Dashboard = require('./Dashboard');
var Comments = require('./Comments');

var Index = React.createClass({
  render: function () {
    var props = this.props; // or possibly this.state
    return (
        <div>
            <header>Some header</header>
            <RouteHandler {...props} />
        </div>
    );
  }
});

The downside of this is you are passing props indiscriminately. So Comments may end up receiving props that are really intended for a different component depending on your routes configuration. It's not a huge deal since props is immutable, but this can be problematic if two different components are expecting a prop named foo but with different values.

Meistro
  • 3,236
  • 2
  • 24
  • 33
  • 1
    What do the 3 periods/dots do or mean in this code: `{...props}` – Giant Elk Apr 04 '15 at 02:00
  • 2
    I guess Flux would avoid the need to send state from the parent App down to a route. I got the above code working, but it's not explicit so the hidden majic is ugly, not easy to trace and track what's going on. – Giant Elk Apr 04 '15 at 02:09
  • 2
    [Spread operator explanation](https://gist.github.com/sebmarkbage/07bbe37bc42b6d4aef81#whats-with-the-weird--notation). It's not explicit but, it's not the worst thing since you are passing props which are immutable. – Meistro Apr 04 '15 at 04:26
  • Here's ReactJS docs on the spread operator: https://facebook.github.io/react/docs/jsx-spread.html and also https://facebook.github.io/react/docs/transferring-props.html – Giant Elk Apr 07 '15 at 02:15
  • this worked for me but the correct syntax is {...this.props} – Win Jul 09 '15 at 14:06
9

In 1.0 and 2.0 you can use createElement prop of Router to specify how exactly to create your target element. Documentation source

function createWithDefaultProps(Component, props) {
    return <Component {...props} myprop="value" />;
}

// and then    
<Router createElement={createWithDefaultProps}>
    ...
</Router>
Andrew Khmylov
  • 712
  • 5
  • 16
7

React Router v 4 solution

I stumbled upon this question earlier today, and here is the pattern I use. Hopefully this is useful to anyone looking for a more current solution.

I'm not sure if this is the best solution, but this is my current pattern for this. I have typically have a Core directory where I keep my commonly used components with their relevant configurations (loaders, modals, etc), and I include a file like this:

import React from 'react'
import { Route } from 'react-router-dom'

const getLocationAwareComponent = (component) => (props) => (
  <Route render={(routeProps) => React.createElement(component, 
{...routeProps, ...props})}/>
)

export default getLocationAwareComponent

Then, in the file in question, I'll do the following:

import React from 'react'
import someComponent from 'components/SomeComponent'
import { getLocationAwareComponent } from 'components/Core/getLocationAwareComponent'
const SomeComponent = getLocationAwareComponent(someComponent)

// in render method:
<SomeComponent someProp={value} />

You'll notice I import the default export of my component as humble camel-case, which lets me name the new, location-aware component in CamelCase so I can use it normally. Other than the additional import line and the assignment line, the component behaves as expected and receives all its props normally, with the addition of all the route props. Thus, I can happily redirect from component lifecycle methods with this.props.history.push(), check the location, etc.

Hope this helps!

Chris
  • 71
  • 1
  • 3
5

You can also combine es6 and stateless functions to get a much cleaner result:

import Dashboard from './Dashboard';
import Comments from './Comments';

let dashboardWrapper = () => <Dashboard {...props} />,
    commentsWrapper = () => <Comments {...props} />,
    index = () => <div>
        <header>Some header</header>
        <RouteHandler />
        {this.props.children}
    </div>;

routes = {
    component: index,
    path: '/',
    childRoutes: [
      {
        path: 'comments',
        component: dashboardWrapper
      }, {
        path: 'dashboard',
        component: commentsWrapper
      }
    ]
}
icc97
  • 8,746
  • 6
  • 60
  • 75
Zhiwei Huang
  • 116
  • 1
  • 5
  • I'm not sure exactly of how this works - but it looks wrong. You're using `this.props` in a function, which I'm pretty sure won't work. If you're using pure functions instead of extending the `React.Component` then you have to pass in `props` as an argument, see the React docs on [Components and Props](https://facebook.github.io/react/docs/components-and-props.html#functional-and-class-components) – icc97 May 27 '17 at 19:24
3

For react router 2.x.

const WrappedComponent = (Container, propsToPass, { children }) => <Container {...propsToPass}>{children}</Container>;

and in your routes...

<Route path="/" component={WrappedComponent.bind(null, LayoutContainer, { someProp })}>
</Route>

make sure the 3rd param is an object like: { checked: false }.

holyxiaoxin
  • 600
  • 1
  • 6
  • 24
3

I have answered this already here.

Here are few ways you can pass props to a route component.

With the react-router v5, we can create routes by wrapping with a component, so that we can easily pass props to the desired component like this.

<Route path="/">
    <Home name="Sai" />
</Route>

Similarly, you can use the children prop in v5.

<Route path="/" children={ <Home name="Sai" />} />

If you are using react-router v4, you can pass it using the render prop.

<Route path="/" render={() => <Home name="Sai" />} />

(originally posted at https://reactgo.com/react-router-pass-props/)

saigowthamr
  • 366
  • 3
  • 7
1

The problem with the React Router is that it renders your components and so stops you passsing in props. The Navigation router, on the other hand, lets you render your own components. That means you don't have to jump through any hoops to pass in props as the following code and accompanying JsFiddle show.

var Comments = ({myProp}) => <div>{myProp}</div>;

var stateNavigator = new Navigation.StateNavigator([
  {key:'comments', route:''}
]);

stateNavigator.states.comments.navigated = function(data) {
  ReactDOM.render(
    <Comments myProp="value" />,
    document.getElementById('content')
  );
}

stateNavigator.start();
graham mendick
  • 1,771
  • 1
  • 16
  • 14
1

Use the component with or without router based on Rajesh Naroth answer.

class Index extends React.Component {

  constructor(props) {
    super(props);
  }
  render() {
    const foo = (this.props.route) ? this.props.route.foo : this.props.foo;
    return (
      <h1>
        Index - {foo}
      </h1>
    );
  }
}

var routes = (
  <Route path="/" foo="bar" component={Index}/>
);

Or your could do it this way:

export const Index = ({foo, route}) => {
  const content = (foo) ? foo : (route) ? route.foo : 'No content found!';
  return <h1>{content}</h1>
};
Michael Hobbs
  • 1,445
  • 1
  • 12
  • 23
1

Use the solution like a below and this works in v3.2.5.

<Route
  path="/foo"
  component={() => (
    <Content
      lang="foo"
      meta={{
        description: lang_foo.description
      }}
    />
  )}
/>

or

<Route path="/foo">
  <Content
    lang="foo"
    meta={{
      description: lang_foo.description
    }}
  />
</Route>
illvart
  • 139
  • 1
  • 7
1

The React Router v5.1 (React >= 16.8) way of doing this:

<Route path="/comments">
    <Comments myprop="value" />
</Route>

Now if you want to access Route Props inside your component then you can refer this solution. In case of functional component, there is another hook useParams() that is not mentioned in that post.

More reference: React Router v5.1

brc-dd
  • 2,351
  • 3
  • 10
  • 25
  • ⚠ CAUTION: You will loose access to ``. The only we can both have the custom props along with the route props is using the `` - render props like this: ` }/>`. – Mr.spShuvo Dec 30 '20 at 00:37
  • @Mr.spShuvo you are wrong. I have updated my answer. Check that out. You just need [`withRouter`](https://reactrouter.com/web/api/withRouter) in case of class components, or need [hooks](https://reactrouter.com/web/api/Hooks) in case of functional components. – brc-dd Dec 30 '20 at 11:17
  • Ok, may be I'm partially wrong. But with class components, you cannot use hooks. Thanks for the update and more reference link. – Mr.spShuvo Dec 30 '20 at 13:27
0

for the react-router 2.5.2,the solution is so easy:

    //someConponent
...
render:function(){
  return (
    <h1>This is the parent component who pass the prop to this.props.children</h1>
    {this.props.children && React.cloneElement(this.props.children,{myProp:'value'})}
  )
}
...
min may
  • 1
  • 1
0

Using a custom route component, this is possible in React Router v3.

var Dashboard = require('./Dashboard');
var Comments = require('./Comments');
var routes = (
  <Route path="/" handler={Index}>
    <MyRoute myprop="value" path="comments" handler={Comments}/>
    <DefaultRoute handler={Dashboard}/>
  </Route>
);

As for the <MyRoute> component code, it should be something like:

import React from 'react';
import { Route } from 'react-router';
import { createRoutesFromReactChildren } from 'react-router/lib//RouteUtils';

const MyRoute = () => <div>&lt;MyRoute&gt; elements are for configuration only and should not be rendered</div>;

MyRoute.createRouteFromReactElement = (element, parentRoute) => {
    const { path, myprop } = element.props;
    // dynamically add crud route
    const myRoute = createRoutesFromReactChildren(
        <Route path={path} />,
        parentRoute
    )[0];
    // higher-order component to pass myprop as resource to components
    myRoute.component = ({ children }) => (
        <div>
            {React.Children.map(children, child => React.cloneElement(child, { myprop }))}
        </div>
    );
    return myRoute;
};

export default MyRoute;

For more details about the custom route component approach, check out my blog post on the subject: http://marmelab.com/blog/2016/09/20/custom-react-router-component.html

François Zaninotto
  • 4,968
  • 31
  • 47
0

this is probably the best way to use react-router-dom with a cookie handler

in index.js

import React, { Component } from 'react'
import {Switch,Route,Redirect} from "react-router-dom"
import {RouteWithLayout} from "./cookieCheck"

import Login from "../app/pages/login"
import DummyLayout from "../app/layouts/dummy"
import DummyPage from "../app/pages/dummy" 

export default ({props})=>{
return(
    <Switch>
        <Route path="/login" component={Login} />
        <RouteWithLayout path="/dummy" layout={DummyLayout} component={DummyPage} 
        {...props}/>
        <Redirect from="/*" to="/login" />
    </Switch>
  )
}

and use a cookieCheck

import React , {createElement} from 'react'
import {Route,Redirect} from "react-router-dom"
import {COOKIE,getCookie} from "../services/"

export const RouteWithLayout = ({layout,component,...rest})=>{
    if(getCookie(COOKIE)==null)return <Redirect to="/login"/>
        return (
        <Route {...rest} render={(props) =>
            createElement(layout, {...props, ...rest}, createElement(component, 
      {...props, ...rest}))
       }
      />
    )
}
Snivio
  • 1,139
  • 10
  • 19
0
class App extends Component {
  constructor(props){
    super(props);

    this.state = {
      data:null
    }


  }
 componentDidMount(){
   database.ref().on('value', (snapshot) =>{
     this.setState({
       data : snapshot.val()
      })
   });
 }

  render(){
  //  const { data } = this.state
  return (
    <BrowserRouter>
      <Switch>
        <Route exact path = "/" component = { LandingPage }  />
        <Route 
          path='/signup' 
          render = { () => <Signup  data = {this.state.data} />} />
        </Switch>
    </BrowserRouter>

  );
  }
};

export default App;
nik.ss
  • 41
  • 1
  • 6