关于webapp架构和reactJs的建议

时间:2015-12-30 12:31:56

标签: javascript jquery mysql elasticsearch reactjs

这个问题更多的是要了解您对我试图解决此问题的方式的看法。 我需要一点ReactJs的专业知识,因为我很新。

首先是一点上下文。我正在使用ReactJs为前端部分开发Web应用程序。 这个webapp将有很多翻译,所以对于维护,我认为最好将所有翻译存储在数据库中,而不是将它们放入文件中。这样我就可以使用sql脚本来管理它们。

我正在使用MySQL数据库作为后端,但出于性能原因,我已将ElasticSearch添加为第二个数据库(嗯,它更像是一个全文搜索引擎)。

因此,一旦应用程序启动,翻译将自动加载到ElasticSearch中。每个翻译都有一个代码和一个文本,所以在弹性搜索中我只加载一个语言环境的翻译(默认为英语),当用户切换语言环境时,会调用加载所选语言环境的所有翻译和更新相应的文字。

这种方式从前端我只能通过代码引用翻译,我将以正确的语言环境翻译文本。

现在,我该怎么做才能做出反应?

到目前为止,我已经编写了一个组件TranslatedMessage,它基本上是在寻找给定的代码,并在呈现此组件时显示它。

在组件代码下方:

import React from 'react';

export class TranslatedMessage extends React.Component {


constructor() {
    super();
    this.render = this.render.bind(this);
    this.componentDidMount = this.componentDidMount.bind(this);
    this.state = {message: ''};
}

render() {
    return (<div>{this.state.message}</div>);
}

componentDidMount() {
    var component = this;
    var code=this.props.code;
    var url="data/translation?code="+code;
    $.get(url, function (result) {
        component.setState({message: result.text});
    });
 }

};

然后我以应用程序的方式使用它,例如翻译'a'链接的标题:

  <a href="index"><TranslatedMessage code="lng.dropdown.home"/><i className="fa fa-chevron-down" /></a>

到目前为止工作正常但问题是我需要刷新整个页面以显示新的翻译,因为我没有更新组件的状态。

现在我的问题是:

1)每当我们在页面中找到组件TranslatedMessage时,就会创建该组件的新实例吗?所以基本上如果我有1000个翻译,那么将创建1000个该组件的实例?然后React必须注意并观察所有这些实例的状态变化?这对表现来说会非常糟糕吗?你有没有找到更有效的方法呢?

2)我不认为强制整个页面重新加载是最合适的方法,但是当用户切换语言环境时,如何更新所有组件的状态?我一直在阅读一个名为Flux的框架(或模式),也许这可能符合我的需求,你会推荐什么?

3)您如何看待在db上存储翻译,我有点担心每次翻译都会向db发送查询,您是否建议使用此方法?

非常欢迎任何建议,改进的想法!

感谢您抽出宝贵时间阅读或获取任何帮助!

1 个答案:

答案 0 :(得分:1)

我为此目的使用基本上是一个Flux商店。在初始化时,应用程序请求使用整个语言文件(这是JSON)并将其推入商店的内存中,就像这样(我现在要假设一个完全平坦的语言文件,而且我&#39 ; m使用ES2015 / 16语法,为了简洁,我省略了错误检查等等:

class I18n {
  constructor() {
    this.lang = await fetch( 'lang_endpoint' )
      .then( res => res.json() )
  }

  get( translation ) {
    return this.lang[ translation ] || null
  }
}

某个地方,我的应用程序在ReactDOM.render( <App /> )或某些变化期间启动,这会使整个事情自上而下(我尽可能地消除状态)。如果我需要切换语言,那么我将绑定change处理程序,以便商店发出change事件,某些代码会触发ReactDOM.render。这是用于更改应用状态的相当标准的Flux实践,关键是尝试消除组件中的状态并将其存储在商店中。

使用I18n类只是在某处实例化它(我通常将它作为从文件导出的单例,例如module.exports = new I18n()require将该文件放入组件并使用{ {1}}方法(这假定某种类型的打包器,例如browserify或webpack,但看起来你的所有复杂性都已排序):

get

此组件也可以简化为

import 'i18n' from 'stores/i18n'

class MyComponent extends React.Component {
  constructor() { ... }

  render() {
    return (
      <span>{ i18n.get( 'title' ) }</span>
    )
  }
}