-
-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Question - Component Distribution #547
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
What kind of component is it? It's quite unordinary that a component starts to manage browser history when it is mounted, unless it's a router itself. What happens if two such components are mounted at the same time? You can definitely call var RouterWrapper = React.createClass({
getInitialState: function () {
return {
routerState: null,
routeHandler: null
};
},
componentDidMount: function () {
Router.run(this.handleRouteChange);
},
handleRouteChange: function(routeHandler, routerState) {
if (this.isMounted()) {
return;
}
this.setState({
routeHandler: routeHandler,
routerState: routerState
});
},
render: function () {
if (!this.state.routeHandler) {
return null;
}
var RouteHandler = this.state.routeHandler;
return <RouteHandler {...this.state.routerState} />;
}
}); I don't think there's a way to tear down a router once it's running though. And again, I doubt it will work with multiple routers on one page. So component doesn't seem like the best abstraction for this anyway. |
Thanks for the reply @gaearon - what you suggest is more or less what I've done now; I agree that it wouldn't make sense for two components to have a fight over the window location :) What bothers me is that react has a nicely declarative and compositional style whereas having the equivalent of a 'main' function in run switches it to something imperative. If someone uses a component that builds a complete interface I'd like them to just know how to use react without having to tell them to call a router function or my own wrapper function that under the hood kicks off the routing cycle. |
What is your use case? What are you building?
New API is a win for everyone who wants to control rendering. It enables stuff like this: var resolveHash = require('when/keys').all;
var SampleHandler = React.createClass({
statics: {
// this is going to be called in the `run` callback
fetchData: function (params) {
return fetchStuff(params);
}
},
// ...
});
Router.run(routes, Router.HistoryLocation, function (Handler, state) {
// create the promises hash
var promises = state.routes.filter(function (route) {
// gather up the handlers that have a static `fetchData` method
return route.handler.fetchData;
}).reduce(function (promises, route) {
// reduce to a hash of `key:promise`
promises[route.name] = route.handler.fetchData(state.params);
return promises;
}, {});
resolveHash(promises).then(function (data) {
// wait until we have data to render, the old screen stays up until
// we render
React.render(<Handler data={data}/>, document.body);
});
}); If you want to encapsulate this in component, you can (as I described above) but it's a leaky abstraction because a router is more akin to observable that tells you what to render, not something to render per se. |
Consider a component that generates routes based on parameters passed to it. Should the user of that component have to kick routing off with a method? I appreciate that there are advantages to the new approach though whether a special method with a callback is quite in line with the way a lot of react/flux apps are structured I'm less certain. In any event I'll continue to experiment with using componentDidMount so I'll close the issue. Thanks for the help @gaearon |
Sorry, I'm still not sure what your use case is so this leaves me confused. Are you building something like a website builder?
Every React app, Flux or not, has a |
With the old API it seemed relatively clear that a component built using react-router could be distributed and used in the ordinary way by someone simply requiring it and using React.render to mount it into the DOM.
With Router.run though it's not clear to me what the best way of distributing the component would be. If someone consumes my component I'd like them to use it like any other react component without having to call a special method to begin routing.
Is the way to achieve this using a wrapper component with Router.run being started in ComponentDidMount?
That way a user could attach the component to the DOM without knowing anything about the react-router API but all the component would do would be to call React.render itself and start routing internally.
The text was updated successfully, but these errors were encountered: