-
-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Suggestions on integration with react-router (Morearty.js) #603
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
Comments
+1 |
+1 A working react-router-morearty integration would be awesome. |
I think this is def possible with new API. Router now just calls you back and it's up to you to do the rendering and pass props. |
@gaearon could you please give a brief code example of how react-router could be set up to pass the current route state object into Morearty? |
@Tvaroh Essentially you need to listen for two things:
The router API is optimized for the first use case, but it should be really easy to make it work with the second as well. I haven't used Morearty before (but it looks awesome! def going to look further into it), so please forgive me if the syntax is off. // This is a reference to my Morearty binding object.
var binding = ...;
// Keep a reference to the "current handler", which is the React component
// class that is at the root of your route hierarchy.
var CurrentHandler;
function renderTheCurrentHandler() {
React.render(<CurrentHandler binding={binding}/>, document.body);
}
binding.addListener(function () {
// This is my notification that something in the binding changed.
renderTheCurrentHandler();
});
Router.run(routes, function (Handler) {
// This is my notification that the route changed.
CurrentHandler = Handler;
renderTheCurrentHandler();
}); Does something like that work for you? |
@mjackson, the problem I'm facing is type error thrown from I guess, if the first render succeeds, subsequent render will return same components from route handlers, is it true? If so, it would be sufficient to ask Morearty to re-render in react-router route callback. To summarize:
Could you suggest something? |
Can you just disable Morearty render callback until router okays it? |
I tried var firstRender = true;
var Bootstrap = Ctx.bootstrap(App);
Router.run(routes, function (Handler) {
if (firstRender) {
React.render(<Bootstrap />, document.body);
firstRender = false;
} else {
Ctx.queueFullUpdate();
b.meta().set('dummy'); // ask to re-render
}
}); but still having the same error. Maybe this is somehow related to the fact I ignore |
Yeah it is related. |
But how can I? |
Can you just make https://github.com/moreartyjs/moreartyjs#starting-the-application Then let react-router do top level rendering with |
Yep, unfortunately still having the same error. var routes = (
<Route name="app" path="/" handler={Ctx.bootstrap(App)}>
<DefaultRoute handler={Dashboard} />
<Route name="inbox" handler={Inbox} />
<Route name="calendar" handler={Calendar}>
<Route name="foo" handler={Foo} />
</Route>
</Route>
);
Router.run(routes, function (Handler) {
React.render(<Handler />, document.body);
}); |
It shouldn't be a problem, I render my app in rAF and it works perfectly with RR. |
Yep, I've removed RAF part from the comment after realizing that the first blocking render isn't performed at all. |
Runnable example: https://github.com/moreartyjs/todomvc-moreartyjs/tree/react-router |
Thanks for TodoMVC link. The issue here is Morearty using I see they offer to pass custom context to This is solvable, just needs more thought. There's probably some simple workaround. |
Can you suggest an alternative to |
Yes, Morearty can wrap its root component into a dynamically generated React class which would provide context via |
Awesome, thank you. Will try to migrate on this approach. |
So there are two ways you can solve this:
|
Yep, I think |
Now that I tried it, seems like RR doesn't pass outer context down so this won't work either. I'm not so sure how to do it now.. |
This is a bit dirty but it works for me: var App = React.createClass({
mixins: [Morearty.Mixin],
render: function () {
return (
<div>
<h1>App</h1>
<RouteHandler />
</div>
);
}
});
var RouterMoreartyWrapper = React.createClass({
contextTypes: {
getRouteAtDepth: React.PropTypes.func.isRequired,
getRouteComponents: React.PropTypes.func.isRequired,
routeHandlers: React.PropTypes.array.isRequired
},
render: function () {
var RouteHandlerWithContext = Ctx.bootstrap(RouteHandler, this.context);
return <RouteHandlerWithContext />;
}
});
var routes = (
<Route handler={RouterMoreartyWrapper}>
<Route name="app" path="/" handler={App}>
<DefaultRoute handler={Dashboard} />
<Route name="inbox" handler={Inbox} />
<Route name="calendar" handler={Calendar}>
<Route name="foo" handler={Foo} />
</Route>
</Route>
</Route>
);
Router.run(routes, Router.HistoryLocation, function (Handler) {
React.render(<Handler />, document.body);
}); |
This is not all context though. You'll need to add https://github.com/rackt/react-router/tree/master/modules/mixins |
This is actually an interesting problem here. Say we have Router and Lib X. Both provide child context. If Lib X doesn't offer a way to specify custom context like Morearty does, we can't use it with Router because there is just no way we can pass that context down. For if Lib X is inside Router, handlers won't get Router's context. If Router is inside Lib X, handlers won't get Lib X's context. I guess it's still an issue Lib X should solve because Router makes more sense at the top. |
Having some problems migrating from contextTypes: { morearty: function () {} } // this is the only way it works to contextTypes: { morearty: React.PropTypes.instanceOf(Context).isRequired }
// or
contextTypes: { morearty: React.PropTypes.object.isRequired }
// or even
contextTypes: { morearty: React.PropTypes.any.isRequired } I get So, when I remove |
@Tvaroh I'm a bit confused. Are you saying approach from this comment isn't working? I think it ran on my computer. |
@gaearon, no, I just tried to migrate from |
Oh. I thought we were talking about making it work with If you want to make |
Yep, I understand that this should work with Your example above worked partially but since I had no time to debug it further. Will reply here when I'll have something to share. |
Can you show the complete changes? I suspect |
I've committed something to the repo above (continuing your example). For a reason wrapper's render is called only once on init. Additionally, if you load app having inbox section in the URL then switching to other sections invokes route handler (it's visible in console log), but switching back to the initial section doesn't call the handler. Also nothing is re-rendered after initial render but I see |
Gave you write permissions to the repo for convenience. |
I'll take a look. Thanks! |
Can asynchronous rendering in handler callback cause problems? It only queues render but the rendering itself is performed in rAF later. |
I have an RR powered app with rAF batching and it works fine. Shouldn't be an issue. |
@gaearon isn't the return value of |
I thought so but it did not work for me that way. Perhaps I made some other mistake though. Need to check again! |
Can't we just do the router stuff in the top level morearty component, sorta like this? #579 (comment) |
This works: http://jsbin.com/duyaxa/4/edit?html,js,output Storing Let me know if I should reopen. |
@ryanflorence unfortunately this wont work on server - |
The trick is to realize "everything is possible with React" Here's your server rendering code 💃 |
Yes, you are correct. Even if this solution feels little bit hacky to me, it works. Thank you very much @ryanflorence. |
going to be hacks when two libs want to own the entry of your app :), fortunately ours is more flexible whereas morearty completely insists on being "first". |
Hello.
I faced a problem of integrating Om-style library (Morearty) with react-router. Problems are:
<Route name="about" handler={ About({ binding: <...> }) } />
.So, as I understand, awesome react-router should just play two roles:
This should be enough to embed the router. Can you provide some feedback if it's possible to use react-router this way?
The text was updated successfully, but these errors were encountered: