-
Notifications
You must be signed in to change notification settings - Fork 154
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
fluxxor with react router 1rc #141
Comments
Now that it's in RC status, I'll definitely get something up soon—I just didn't want to rewrite the example every time a beta was released. :) In the meantime, if you use var flux = new Fluxxor.Flux(...);
// make sure react router injects the `flux` prop
// into every component it instantiates
function createFluxComponent(Component, props) {
return <Component {...props} flux={flux} />;
}
var router = (
<Router history={history} createElement={createFluxComponent}> |
Everything seems to work fine with the setup described here but I do see the following warning from React
Even after reading the page linked to in the warning I'm not sure how to avoid it. Any ideas? |
@andrewslater I don't think I've seen that in a while with Fluxxor + React Router. Do you have a small reproducible example I can take a look at? |
I tried reproducing this in the react-router example by migrating it to use react-router 1.0-rc1 however everything seems to be working fine after I made the changes! I will continue to explore the issue in the codebase I'm working in where this problem remains. I've submitted a pull request which includes my changes to upgrade to react-router 1.0-rc1 as I imagine that will be something the fluxxor project will want at some point. The API for react-router has changed enough that it did require some fairly widespread changes within the example. |
Thanks for the example Andrew. Hey guys, what if I wanted to have a wrapper around all my pages that has the flux instance and some ui like a header. I can't put it in an 'empty-view' since that doesn't have the flux instance right? |
@FutureKode In the example Andrew added, every route handler that React Router renders gets the flux instance as If you wanted some UI, just create a new component (e.g. <Router ...>
<Route component={AppContainer}>
/* other routes here */
</Route>
</Router> It's possible, though, that Whenever React Router (1.0-rc1+) renders a route handler, it will render all the parent route handlers that contain it, including ones that don't have a const router = () => {
return (
<Router history={history} createElement={createFluxComponent}>
<Redirect from="/project/:project_id" to="/project/:project_id/tree" />
<Route component={Application}>
<Route component={Auth}>
<Route component={ProjectList} path="/" />
<Route component={Project} path="project/:project_id">
<Route components={ProjectSettings}>
<Route components={{
generalSettingsEditor: ProjectGeneralSettings,
hcDataKeysEditor: ProjectHcDataKeysEditor,
aclEditor: ProjectAclEditor,
importExport: ProjectImportExport,
projectDeletePane: ProjectDeletePane
}} path="/settings" />
</Route>
<Route component={ProjectHcBank} path="/bank" />
<Route component={ProjectTreeEditor} path="/tree" />
</Route>
</Route>
</Route>
</Router>
);
} In this example, going to <Application>
<Auth>
<Project>
<ProjectTreeEditor />
</Project>
</Auth>
</Application> because the matched route is contained by |
Thanks man, that works. Only thing is I get
I'm probably doing something wrong |
@FutureKode if you ever figure out how to avoid that warning please let us know. Like you, everything seems to be working fine for me but I've not been able to determine what the cause is (and it drives me crazy seeing it in my js console log!) |
Upgraded to react 0.14.0 and I no longer get this warning :) |
Sweet! Thanks for letting us know... time to upgrade my reactjs too :) |
@andrewslater that just because that warning was removed in 0.14. So absence of waring doesn't mean that there is no bug connected to context ;) |
@FutureKode @andrewslater Since the owner tree is a subset of the parent tree, it's possible there was no issue here; React was just informing you that the context from the parent and the context from the owner were different. It might be more obvious if we could see your route config, the entry point into your application, and the component where |
Hey @BinaryMuse , thanks for looking. routes.jsvar React = require("react"),
ReactRouter = require("react-router"),
Route = ReactRouter.Route;
var AppContainer = require('./components/app-container.js'),
LandingPage = require("./components/landing-page.js"),
MenuPage = require("./components/menu-page.js"),
PaymentPage = require("./components/payment-page.js"),
ConfirmationPage = require("./components/confirmation-page.js"),
ClosedPage = require("./components/closed-page.js");
var routes = (
<Route component={AppContainer}>
<Route component={LandingPage} path="/" />
<Route component={ClosedPage} path="/closed" />
<Route component={ConfirmationPage} path="/confirmation" />
<Route component={MenuPage} path="/menu/:restaurant_id" />
<Route component={PaymentPage} path="/payment" />
</Route>
);
module.exports = routes; app.jsvar React = require('react'),
ReactRouter = require("react-router"),
Fluxxor = require('fluxxor');
var actions = require("./actions"),
routes = require('./routes'),
AppStore = require("./stores/app_store"),
OrderStore = require("./stores/order_store"),
RouteStore = require("./stores/route_store"),
UserStore = require("./stores/user_store");
var Router = ReactRouter.Router;
var createBrowserHistory = require('history/lib/createBrowserHistory');
var history = createBrowserHistory();
var stores = {
AppStore: new AppStore(),
OrderStore: new OrderStore(),
RouteStore: new RouteStore({router: Router, history: history}),
UserStore: new UserStore()
};
var flux = new Fluxxor.Flux(stores, actions);
flux.on("dispatch", function(type, payload) {
console.log("Dispatch:", type, payload);
});
var createElement = function(Component, props) {
return <Component {...props} flux={flux} />
}
React.render(
<Router createElement={createElement} history={history} routes={routes} />,
document.getElementById('app')
); landing-page.jsvar React = require("react"),
Fluxxor = require('fluxxor'),
FluxMixin = Fluxxor.FluxMixin(React),
StoreWatchMixin = Fluxxor.StoreWatchMixin;
var Footer = require('./footer'),
RestaurantSelect = require('./restaurant-select'),
PostcodeInput = require('./postcode-input');
var geolocation = require('geolocation');
var LandingPage = React.createClass({
mixins: [
FluxMixin,
StoreWatchMixin("AppStore", "OrderStore", "UserStore")
],
componentWillMount: function() {
document.body.id = 'landing_page';
},
getStateFromFlux: function() {
var flux = this.props.flux;
return {
app: flux.store("AppStore"),
order: flux.store("OrderStore"),
user: flux.store("UserStore")
};
},
getUserLocation: function() {
geolocation.getCurrentPosition(function (err, position) {
if(err) console.log(err);
else {
this.getFlux().actions.user.setLocation({
lat: position.coords.latitude,
lng: position.coords.longitude
});
}
}.bind(this));
},
render: function() {
var deliverClasses = 'module hidden';
if(this.state.app.doesDeliver === true) deliverClasses = 'module';
return (
<div>
// some stuff in here
</div>
)
}
});
module.exports = LandingPage; route_store.jsIs it correct to pass history into here from app.js, like: var Fluxxor = require('fluxxor'),
Constants = require("../constants");
var actions = require("../actions");
var RouteStore = Fluxxor.createStore({
initialize: function(options) {
this.router = options.router;
this.history = options.history;
this.bindActions(
Constants.ROUTE_TRANSITION, this.handleRouteTransition
);
},
handleRouteTransition: function(payload) {
var path = payload.path,
params = payload.params;
this.history.pushState(null, path, params);
this.emit("change");
}
});
module.exports = RouteStore; |
@FutureKode Okay, here's what's happening: In React 0.13, React warned you about the differences between owner context and parent context. The definitions are:
I like to think of them as "context at instantiation time" and "context at render time." In React Router <1.0, you (the user) were responsible for creating the component instance: var MyComponent = React.createClass({
mixins: [FluxMixin],
render() {
return <RouteHandler />;
}
}); Since you both instantiated and also rendered the component referenced by In React Router >=1.0, you (the user) simply receive new route handler as already instantiated components: var MyComponent = React.createClass({
mixins: [FluxMixin],
render() {
return <div>{this.props.children}</div>;
}
}); That means some other entity (the router) created an instance of In React 0.13, to fix this, you'd need to change it so that the router inherited your own defined context by rendering it inside a component you owned: const App = React.createClass({
mixins: [FluxMixin],
render() {
return <Router createElement={createElement} routes={routes} />;
}
})
React.render(
<App flux={flux} />, document.getElementById('app')
); Now, the router's owner and parent context are defined by The reason this wasn't an issue in your case is because you're using |
@BinaryMuse thank you for explanation |
@BinaryMuse Yes, thanks a lot for this excellent explanation. Your fix worked for React 0.13 && the warning doesn't show for React 0.14 with the way I had it :) |
Hello, would you be so kind as to provide a full example of using fluxxor with the latest react router? It's not making sense to me :(
The text was updated successfully, but these errors were encountered: