So, I am designing a ReactJS web-client for a buddy that collects information from a server about users and lets the user interact with the sever data. I am also trying to comply to ReactJS/FLUX design patterns, using stores, dispatchers, and events. Learning all this can be difficult. But with React, solutions to large problems can contain shockingly simple solutions.

I have a header component, and I wanted to only show the search widget that resides in it when it is relevant, otherwise, it was out of context. So, my top header component looked something like this:

Original default header

What I wanted, is for when I’m not on the results page, for it to look like this:

app-header-default

I envisioned the solution to involve more code than it did… After some researching I learned that routes other than the top level route can have multiple components passed in, and devoured by the app-template’s props.

(All following code is ES6)

For the sake of brevity, assume Template, AppList, Result SearchHeader, ResultItemDetail and DefaultHeader as well other required imports for react and react-router are in the code.

My initial router file looked something like this:

app.js

app-old

My initial template file looked something like this:

app-template.js

app-template-old

The solution involves react-router properties, and the fact that you can pass in more than one component. Turns out this feature can make life easy for those who realize this.

To implement multiple components in a route, instead of something like

component={ Result }

You can do something like

components={{ main: Result, widget: SearchHeader }}

Here is the new code for both my router file and my app-template that uses a different widget for different routes:

app.js

app

app-template.js

app-template

Notice that now, I am not passing in props.children, but instead, props.widget and props.main, inherited from the router’s properties, i.e. the components in the object passed in from the router:

components={ {main: ..., widget: ...} }.

Basically props.main and props.widget are inherited from the route.

This allows me to define two separate widgets in my route file, and hand them down to a component route easily, without altering anything else in my code-base. I did have to create two separate widgets, one for the search render, and one for the “Go back” render, but that’s a minor problem.

Here are pictures of the two separate header widgets:

honeypot-wdget-search

honeypot-widget-default

So, the solution was found was built into the property values of react-router from NPM. I hope this helps some of you. JavaScript on.

Share on FacebookEmail this to someoneTweet about this on TwitterShare on Google+Share on LinkedInShare on Reddit