React Router和React Intl:有没有更好的方法来动态加载翻译's路线

React-Router and React-Intl: Is there a better way to load dynamically the translation's route?

本文关键字:React 翻译 加载 路线 动态 方法 Intl Router 有没有 更好      更新时间:2024-04-06

当页面的路由发生变化时,我会动态加载页面的翻译。我对每条路线都使用onEnter。

有没有更好的方法来实现这一点?我可以避免对每条路由使用onEnter回调函数吗?

var  Root = React.createClass({       
    baseTranslations : {},
    getInitialState: function(){    
        return {
            lang: 'it',
            translations: null,
        };    
    },    
    componentWillMount: function() {    
        // load the common translation for all routes            
        this.setState({
            lang: this.getLocale().lang
        }); 
        this.loadTranslation("base");
    },
    onChangeRoute: function(nextState, replace){
        // load the specific route's translation
        this.loadTranslation(nextState.location.pathname);
    },
    getLocale: function(what){
        // return lang and user region (ex: it-IT)    
    },
    loadTranslation: function(route){    
        var lcl = route;    
        var mapping = {
            '/'     : 'home',
            'auth'  : 'dashboard'
        };
        if(route in mapping){
            lcl = mapping[route];
        }
        $.ajax({
            url: './locales/' + this.state.lang +'/' + lcl + '.json',
            dataType: "text",
        }).done(function(res) {
            if(lcl === "base"){
                this.baseTranslations = JSON.parse(res);
            }
            this.setState({
                translations: $.extend(true, this.baseTranslations, JSON.parse(res))
            });
        }.bind(this));
    },
    render: function() {
        var children;
        if (this.state.translations) {
            children = (
                <IntlProvider locale={this.state.lang} messages={this.state.translations}>
                    <Router history={browserHistory}>
                        <Route path="/" component={App}>
                            <IndexRoute component={Home}/>
                            <Route path="signup"  onEnter={this.onChangeRoute} getComponents={(location, cb) => {
                                 require.ensure([], (require) => {
                                        cb(null, require('./components/Signup.jsx'))
                                 }, "Signup")
                            }} />     
                            <Route path="*" component={NoMatch}/>
                        </Route>
                    </Router>
                </IntlProvider>
            );
        }
        return <div>{children}</div>;
    }
});

ReactDOM.render(
    <Root/>,
    document.getElementById('rct-cont')
);

由于很难说要使用哪个Flux实现,我将在这里为您提供伪代码和关键思想:

i18nActions

  • loadLanguage(language, route)-如果给定路由的语言尚未加载,则会触发查询,然后将结果委托给存储
  • 如果需要,可以在此处实现缓存层(localStorage)。不过,您需要小心失效。您应该有某种方法来判断数据已经过时,需要刷新

i18n存储

  • 保持i18n状态对用户可见。您将从UI级组件中使用此状态

  • onEnter触发loadLanguage以更新存储
  • 消耗存储并将数据传递给IntlProvider。其他组件可以从该上下文中挖掘i18n数据

还有一些额外的问题,比如在加载翻译时该怎么办。那你应该展示什么?您可以推迟向用户显示UI,也可以使用占位符,一旦收到数据,占位符就会被替换。