-
-
Notifications
You must be signed in to change notification settings - Fork 10.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to pass init data with server rending in rc-1 #1969
Comments
I'd like to know this as well. Currently I'm doing it in a very hacky way: var routes = function(store){
return (
<Route component={App} store={store}>
<Route path="/" component={Main}/>
</Route>
)
};
export default routes; "store" is what I'm injecting into props. match({routes: routes(store), location}, (error, isRedirect, renderProps) => {
ReactDOMServer.renderToString(<RoutingContext {...renderProps}/>),
}); And then I use it like this in my App component this.props.route.store This seems very wrong but it works. Can anyone help us out here? |
Try the following, it should work :) Inject "store" through createElement. ...
match({routes, location}, (error, isRedirect, renderProps) => {
function createElement(Component, props){
return <Component {...props} {...store} />;
}
return doSomething({
renderProps: <RoutingContext {...renderProps} createElement={createElement}/>,
});
});
... |
The RoutingContext source code It does't pass the customize props to the Router, only the React-router pre-define props. I tried merge the inject data to the this.props.params like this: assign(renderProps.params,injectData); but I think this is a wrong way too. |
This is my current approach: import React from 'react';
class DataWrapper extends React.Component {
getChildContext () {
return {
data: this.props.data
};
}
render () {
return this.props.children;
}
}
DataWrapper.childContextTypes = {
data: React.PropTypes.object.isRequired
};
export default DataWrapper; so you can use it on the server like: // data is fetched from mongo or whatever
ReactDOMServer.renderToString(<DataWrapper data={ data }><RoutingContext {...renderProps}/></DataWrapper>) or on the browser like: var data = JSON.parse(document.getElementById('data').innerHTML),
history = createBrowserHistory();
ReactDOM.render(<DataWrapper data={ data }><Router history={ history }>{ routes }</Router></DataWrapper>, document.getElementById('app')); What do you think? |
How are you passing the props from DataWrapper to the routed components? |
@nightwolfz, using context like: class SomeRoutedComponent extends React.Component {
constructor (props, context) {
super(props, context);
this.state = context.data.someData;
}
}
SomeRoutedComponent.contextTypes = {
data: React.PropTypes.object.isRequired
};
export default SomeRoutedComponent; |
@coma Thanks! Works wonderfully! |
Thanks for answering @coma |
@coma where is the |
@brickyang it's present in my index.html! My approach is slightly different now that I'm using https://github.com/rackt/react-redux, but the store rehydration on the client side looks pretty similar to the example above. |
@coma Got it. Thx! |
Does it feel wrong to anyone else that this should be closed because you can hack around the issue using an experimental React feature that's likely to break in future releases? Is there a downside to just allowing arbitrary props to be passed down instead, so that @nightwolfz's |
``` javascript``
match({routes,location}, (error, redirectLocation, renderProps) => {
The text was updated successfully, but these errors were encountered: