javascript - 关于 webapp 架构和 ReactJs 的建议

标签 javascript jquery mysql elasticsearch reactjs

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

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

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

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

这样,从前面我就可以仅通过代码引用翻译,并且我会将文本翻译成正确的语言环境。

现在,我该如何在 react 中做到这一点?

到目前为止,我已经编写了一个组件 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)您对将翻译存储在数据库上有何看法,我有点担心为每个翻译向数据库发送查询,您会推荐还是不推荐这种方法?

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

感谢您花时间阅读本文或提供任何帮助!

最佳答案

我基本上使用 Flux 存储来实现此目的。初始化时,应用程序请求使用整个语言文件(JSON),并将其插入存储中的内存中,如下所示(我现在假设一个完全平面的语言文件,我正在使用 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 /> )期间启动。或一些变化,这使得整个事情自上而下(我尝试尽可能地消除状态)。如果我需要切换语言,那么我会绑定(bind) change处理程序,使商店发出 change某些代码听到的事件会触发 ReactDOM.render 。这是更改应用程序状态的相当标准的 Flux 实践,关键是尝试消除组件中的状态并将其存储在存储中。

要使用I18n类只是在某处实例化它(我通常将其作为从文件导出的单例,例如 module.exports = new I18n()require 该文件到您的组件中并使用 get 方法(这假设某种打包程序,例如 browserify 或 webpack但看起来你已经把复杂性全部排序了):

import 'i18n' from 'stores/i18n'

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

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

这个组件也可以简化为

const MyComponent = props => <span>{ i18n.get( 'title' ) }</span>

关于javascript - 关于 webapp 架构和 ReactJs 的建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34529633/

相关文章:

MySQL CASE WHEN THEN 空大小写值

javascript - 将谷歌我的地点 map 中的数据添加到自定义谷歌地图

Javascript、Twitch API 调用、重复图像/空返回

javascript - 如何在 Javascript 中传递 HTML 数据

javascript - 如何多次使用州下拉菜单和城市下拉菜单javascript而不影响其他下拉菜单

javascript - jQuery .click() 在搜索建议中不起作用

php - MySQL 取反值(NOT 运算符)

Javascript 时间复杂度分析

javascript - 在脚本中重定向

mysql - 我想获取所有大于数据库中给定日期的记录