2015-12-30 3 views
0

Этот вопрос больше, чтобы узнать ваше мнение о том, как я пытаюсь решить эту проблему. Мне понадобится немного опыта ReactJs, поскольку я совершенно новый.Советы по архитектуре webapp и reactJs

Сначала немного контекста. Я разрабатываю веб-приложение, использующее ReactJs для части интерфейса. У этого 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}); 
    }); 
} 

}; 

И тогда я использую его в пути whis приложения, например, чтобы перевести название на «а» ссылка:

<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

Я использую для этого в основном магазин 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 />) или некоторые вариации, и это делает все это сверху вниз (я стараюсь, чтобы устранить состояние как много насколько это возможно). Если мне нужно было переключать языки, я бы привязал обработчик 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> 
+0

Спасибо только один вопрос более,! для использования ждут, функция должна быть помечена как async, но конструкторы не могут быть асинхронными, как вы это решаете? – fgonzalez

+0

его в конструкторе только для краткости. Я извлечу этот раздел загрузки в отдельную функцию и вызову, что после создания магазина. Немного неудобно, но отлично работает. В качестве альтернативы вы могли бы использовать обещания и хранилище, когда оно было загружено/готово, это фактически изменение данных, поэтому я бы просто выпустил событие изменения, которое вы уже обрабатываете, чтобы повторно отобразить свое приложение. –