这个问题更多的是想了解您对我尝试解决此问题的方式的看法。 我需要一点 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/