I'm building an Isomorphic app using React, react-router v3 and material-ui. One of the requirements of material-ui in server-side rendering is to pass to the theme the client's user agent, so MUI will be able to prefix their inline styles accordingly.
Originally the root component of the app was the router, i.e on the server side:
<RouterContext {...renderProps}/>
And on the client:
<Router children={routes} history={browserHistory} />
Now, since I didn't know how to pass the user agent to the RouterContext
on the server, I came up with an (ugly?) solution: I've created a useless component named Root, to whom I passed the user agent, and Root had the router as his children
, i.e. on the server side:
<Root userAgent={userAgent}>
<RouterContext {...renderProps}/>
</Root>
and on the client:
<Root>
<Router children={routes} history={browserHistory} />
</Root>
Now, everything works well but I don't really like creating that useless element if I don't have to, so my question is - is there a better way?
Can I somehow pass the user agent to RouterContext
on the server, which will in turn pass it to the Index Route which will create the theme?
Here's the code of Root
if someone's interested:
class Root extends React.Component {
constructor(props){
super();
this.muiTheme = getMuiTheme(customTheme, { userAgent: props.userAgent });
}
render () {
return (
<MuiThemeProvider muiTheme={this.muiTheme}>
{this.props.children}
</MuiThemeProvider>
);
}
}
React components use props to communicate with each other. Every parent component can pass some information to its child components by giving them props. Props might remind you of HTML attributes, but you can pass any JavaScript value through them, including objects, arrays, and functions.
Steps: Embed the child component to the parent component. Pass the props to the child component as an argument while embedding it to the parent component. In the child component, access the data variable value by writing the name or variable only.
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. Similarly, you can use the children prop in v5. If you are using react-router v4, you can pass it using the render prop.
Conclusion: Use {… Instead, to pass all React props from parent to child at once, you need to take advantage of the spread operator ( ... ). The spread operator lets you pass the entire props object to a child component as that child's props object.
You can use createElement
on RouterContext
to achieve this.
<RouterContext
{...renderProps}
createElement={(Component, props) => <Component {...props} userAgent={data.userAgent} />}
/>
This will make userAgent
available in the props of all route components.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With