-
-
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
What is the recommended way to integrate FormatJS? #484
Comments
FWIW I wrap my Routes in a top-level Route for this reason (and to handle a little bit of global render-dependent bootstrapping). |
Thanks, @Jbelcher. I was converging there, as well, so that gives me some confidence I’m not making a mistake here :) |
I also do that. |
the new API in 0.11 makes this simple: Router.run(routes, function(Handler) {
React.render(<Handler locales={i18n.locales}/>, document.body);
}); |
@gaearon @rpflorence any idea how to update that If I call |
I asked about this more generally on the Reacr-Intl project and basically they intend you to reload the page to switch UI language Alan
|
Why not do this? var CurrentHandler = null;
function renderApp() {
if (CurrentHandler) {
React.render(<CurrentHandler someProp={something} />, document.body);
}
}
Router.run(routes, function(Handler) {
CurrentHandler = Handler;
renderApp();
});
something.onChange(function () {
renderApp();
}); |
wow @gaearon awesome !! that was simple! 👍 |
Yeah I saw @rpflorence write a very similar example in some other issue. Probably worth adding a section to the docs, since it's a very common pattern! |
as for Version 1.0.0 beta3, we can do: var DefaultMessages = require("./../i18n/en");
var App = React.createClass({
mixins: [IntlMixin, State],
contextTypes: {
router: React.PropTypes.func.isRequired
},
getDefaultProps: function(){
return {
locales:["en-CA"],
messages:DefaultMessages
};
},
render: function(){ ... }
}); |
Hi @DEllement , can you explain more of what you did to get IntlMixin to work with 1.0.0 beta3? I can't seem to pass the {locales, formats} object for react-intl with the mixin at all in the router, works fine without using the router though. |
Hi, basically, App is my main Application Component it hold my global state for the whole application. getDefaultProps is called the first time the Component is created which return an obj with 2 properties : locales & messages. As long as those 2 properties return the correct objects ( an array of string & a json object ). Others in that thread was suggesting to pass those object as properties in the Handler rendering call. It didn't seam possible in 1.0.0beta3 so i decided that it will do the same things to pass those props inside getDefaultProps of my main Application Component. Although it make your component tightly coupled with those properties i don't think its a real problem for now. Also take note that your ReactComponent need the IntlMixin Sorry for reply 6 days later and i hope it help somebody. :) |
@DEllement Your way will cause a warning, Like below
It because IntlMixin requires a context from owner, but in this situation, your component's owner is React Router, But not your My way is add Here is my code. I think this is the best way to integrated react-intl and react-router, any idea?
|
Sorry, I'm using 1.0.0 beta3, I have not tested it on 0.13.3. You could On Fri, Aug 21, 2015 at 10:35 PM, apreg notifications@github.com wrote:
|
Yeah, I just did that. Sorry for my lame question. By the way after the upgrade I get
|
Sorry, I only use react-router in client side..., so afraid I can't answer On Sat, Aug 22, 2015 at 2:07 AM, apreg notifications@github.com wrote:
|
I use it on client side too. :) |
Adding history prop was the key. So, it does not throw those exceptions anymore. Thx.
|
@garbin could you share the part where you integrate the IntlMixin mixin into the extended Router class, and where you set this.props.intl? I would like to test your code with these details. The purpose is to centralize the calls to get the locale messages & formats from the router component so that all child components can access react-intl from the router, instead of adding a mixin on each child component. Thanks, |
Yes, It's dead simple:). just two steps, take it. 1.create a Component through React.createClass(), Mixins only works here.
2.All of your component extends from BaseComponent, It'll be work.
This is not perfect, but it works! On Sat, Aug 29, 2015 at 2:17 AM, pbreah notifications@github.com wrote:
|
@garbin thanks for your quick response. Merging these with the mixin feature and class inheritance is a good way to solve it, but we end up with two parent classes: import React from 'react';
import { history } from 'react-router/lib/BrowserHistory';
import {Router as ReactRouter, Route} from 'react-router';
import AsyncProps from 'react-router/lib/experimental/AsyncProps';
import ReactIntl from 'react-intl';
var rootRoute = {
path: '/',
childRoutes: [
require('./routes/path1'),
require('./routes/path2')
],
component: require('./components/App')
};
// here is the mixin that adds IntlMixin
var BaseComponent = React.createClass({
mixins:[ReactIntl.IntlMixin]
});
// this similar to your example above
class Router extends ReactRouter {
static get childContextTypes(){
return Object.assign(super.childContextTypes, {
locales: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.array
]),
formats : React.PropTypes.object,
messages: React.PropTypes.object,
getmsg: React.PropTypes.func
});
}
getChildContext() {
var i18nLoader = require('i18n');
var context = super.getChildContext() || {};
context.locales = this.props.locales || ['en'];
context.formats = this.props.formats || {};
context.messages= this.props.messages|| {};
return context;
}
}
// Now need to inherit from Router and BaseComponent
// ran out of options as there is no multiple inheritance:
class BaseRouter extends Router {
// BaseComponent??
}
React.render((
<BaseRouter
children={rootRoute}
history={history}
createElement={AsyncProps.createElement}
/>
), document.getElementById('main-content')); Any ideas how to approach this? how did you do your final implementation on your code with a centralized react-intl? Thanks, |
@pbreah The component I mentioned above is |
Here is what I did. I know it 's a different approach but maybe someone can get something out of it. There is this react-intl-es6 repo. I've extended Intl like this in my App component:
then in app.js
and in LoginScreen.js
|
@garbin and @apreg thanks for helping. I finally got it working. I had to integrate it on the context (this.context) on the App component, then passed this to the children using a hack to propagate the "context" as custom props to the child components on the render method (for anyone that needs it): // hack until React 0.14 is released.
var bodyComponent = React.Children.map(this.props.children, function(child) {
return React.cloneElement(child, {
locales: this.props.locales,
messages: this.props.messages
});
}.bind(this)); |
Yeah, I guess that's what |
@apreg , I'm trying to get it working on my side too but I'm having an issue with react-intl-es6 I get the following error: When I want to do: Also
Do you have an idea? |
@jonaswindey You get undefined Intl probably because it is not exported. To solve this I added these few lines to
|
Hm, thanks for the tip. Seems a bit dirty though (and every npm install will overwrite this) |
Yeah, I agree. Maybe a pull request would be appropriate in this case but I'm too lazy right now :) |
@jonaswindey thx 👍 |
Hi All I have found a good solution to be to transferring props to children as in see : https://github.com/rackt/react-router/blob/master/UPGRADE_GUIDE.md so my code is something like function renderApp(i18n) { var React = require('react'); var App = React.createClass({ render: function () {
}); var rootRoute = { React.render( } now I can access my required locales / messages in any child component of loaded view. |
Tha should be |
I canot find a working example of implementing format.js, I browsed thru all the suggestions but I canot find a one that is working, could someone please give a working gist or something ? |
+1 |
Wrap your |
@taion got it thanks for the response! |
To re-render the app for a different locale, a container is recommended (https://facebook.github.io/react/blog/2015/10/01/react-render-and-top-level-api.html). An example of the approach for React 0.14.*:
Then the locale changer component can call:
|
@slimjim777 When i call rerender, i got the following warning. How can avoid it? warning.js:44 Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the undefined component. |
@KingWu You could try wrapping the call with a check for isMounted(). |
FormatJS illustrates the following example integration with React, using their React mixin (react-intl).
where
Container
uses theReactIntlMixin
mixin.Any children of
Container
get thei18n
data (locales & messages) for free (if they also use theReactIntlMixin
) thanks to react-intl's usage of React’scontext
.I am experiencing difficulty integrating FormatJS into my React-Router-based project. The ridiculously naïve approach of attaching
locales
andmessages
as props to myRouter
fails to provide the necessary context.Is my only option setting this data as props on my actual handlers?
The text was updated successfully, but these errors were encountered: