I followed https://github.com/rackt/react-router/blob/e43293d873abb985d4120f33b7955fc5269341fe/docs/guides/flux.md so I could have access to the router from inside of my Stores/Actions in case some business logic needs to trigger a transition to another page without any user interaction.
However, I would like to have access to the current location's params/query string -- is there any way that I can get that from the router instance (or a way to get at the location instance of the router?)
You can have your own RouterStore. Fire an action from Router.run callback to fill it with state.
Added to docs: https://github.com/rackt/react-router/commit/d69f1c1405cf831319b9a1ac98a8ffccefab2329.
Closing the issue. Please let me know if I missed something!
Works like a charm, thank you!
I am trying to use this technique but I think I am doing something wrong... As you suggested, I have a RouteStore and RouteActions firing the following:
Router.run(routes, Router.HistoryLocation, function(Handler, state) {
RouteActions.queryChange({params: state.params, query: state.query});
React.render(<Handler />, document.getElementById('app'));
});
I have a component that on componentDidMount checks for current query in the url and if it's empty, it adds some default values using Navigation.replaceWith. I see then how it calls Router.run with the new parameters and it fires the Action. Then, my component, also in componentDidMount, calls Rest.request (which takes the parameters from RouteStore). The problem is that this Rest.request gets called before the store gets updated so... It makes the request with the wrong parameters.
@ferrannp Instead of redirecting on mount, do it on static willTransitionTo method by calling transition.redirect.
Mmmm I am not sure if that would be a solution? The reason I am using replaceWith is because Does not add an entry into the browser history.
So what I want to do is update the parameters in the url and then, my utility Rest class can make requests using those parameters. For me the easiest way would be:
Router.run(routes, Router.HistoryLocation, function(Handler, state) {
Rest.setCurrentParams(state.query);
React.render(<Handler />, document.getElementById('app'));
});
Rest is not a store, just as I said, a class with some methods to fetch data. Actually, I am not sure why I would need a RouteStore if I don't have any component listening for it. However, this way of setting parameters seems to break the Flux diagram... Therefore I am still not sure. The truth is that the useful "State" mixin can only be use within a React component...
I understand why you're using replaceWith. The reason I suggest using transition.redirect in a willTransitionTo is it will avoid adding hitting the route in the first place. Transition hooks run before pushing to the history.
Try it.
Ok, I understand I can do this:
Router.run(routes, Router.HistoryLocation, function(Handler, state) {
RouteActions.queryChange({params: state.params, query: state.query}):
React.render(<Handler />, document.getElementById('app'));
});
And in my component:
statics: {
willTransitionTo: function(transition, params, query, callback) {
if(query.myParam === undefined) {
transition.redirect('/MyRoute', {}, {myParam: 'defaultParam'});
}
}
},
This works great cause it hitting Router.run only once. But I am still not sure where to call Rest.request. Where can I be sure that my RouteStore will be up to date?
This is my ugly workaround:
Router.run(routes, Router.HistoryLocation, function(Handler, state) {
handleChange = function() {
RouteStore.removeChangeListener(handleChange);
React.render(<Handler />, document.getElementById('app'));
};
RouteStore.addChangeListener(handleChange);
RouteActions.queryChange({params: state.params, query: state.query});
});
Oh I see some workarounds in #530 and they are pretty similar. Thank you for your help @gaearon
How can I do similar stuff with 1.0?
For questions and support, please visit our channel on Reactiflux or Stack Overflow. The issue tracker is exclusively for bug reports and feature requests.
@taion ok, Thanks