2016-06-28 10 views
0

У меня есть приложение RefluxJS, которое имеет несколько хранилищ и довольно глубокую иерархию компонентов. Я попытался сделать компоненты очень независимыми, каждый из которых подключается к магазинам, которые он должен отображать; и сами магазины иногда вызывают действия, которые прослушивают другие магазины.Метод reactJS render(), вызываемый чаще, чем необходимо, в сложном приложении RefluxJS

Я обнаружил, что получаю много ложных вызовов методам render() моих компонентов, потому что два магазина могут прослушивать одно и то же действие, а различные компоненты в иерархии могут прослушивать эти разные магазины. Это влияет на работу пользователя, потому что иногда есть немного отставания.

Вот код:

var Actions = Reflux.createActions(['changeUser']); 
Actions.changeUser.preEmit =() => console.log('Action emit: changeUser'); 

var UserStore = Reflux.createStore({ 
    listenables: [Actions], 

    onChangeUser(user) { 
    this.trigger(user); 
    } 
}); 

var MessageStore = Reflux.createStore({ 
    listenables: [Actions], 

    onChangeUser(user) { 
    setTimeout(() => { 
     // pretend we had to go to an API or something to get this 
     var message = "Welcome to the app!"; 
     this.trigger(message); 
    }, 500); 
    }, 
}); 

var App = React.createClass({ 
    mixins: [Reflux.connect(UserStore, 'user')], 

    render() { 
    console.log('Component render: App'); 

    if (!this.state.user) { 
     return (
     <button onClick={() => Actions.changeUser('Some User')}> 
      Click to make stuff happen 
     </button> 
    ); 
    } 

    return (
     <div> 
     <div>Hello, {this.state.user}.</div> 
     <Message/> 
     </div> 
    ); 
    } 
}); 

var Message = React.createClass({ 
    mixins: [Reflux.connect(MessageStore, 'message')], 

    render() { 
    console.log('Component render: Message'); 

    return <div>Your message: {this.state.message}</div>; 
    } 
}); 

ReactDOM.render(<App/> , document.getElementById('app')); 

Fiddle: https://jsfiddle.net/9xwnxos6/

Это путь упрощенно (в этом примере я бы, вероятно, просто добавить индикатор загрузки какой-то), но иллюстрирует основную проблему, вы можете видеть, как пользовательский интерфейс переходит через промежуточные состояния, когда вы делаете что-то.

Как я могу улучшить свой дизайн React/Reflux, чтобы избежать нескольких попыток запуска из одного взаимодействия?

+0

Возможно, этот случай слишком изобретателен, чтобы быть полезным. Я не вижу никакого «дополнительного рендера» здесь. Что вы хотите, чтобы произошло с пользовательским интерфейсом между нажатием кнопки и приходом сообщения? Если ваша жалоба заключается в том, что вы не хотите отображать «Сообщение» до того, как ваше сообщение будет доступно, просто улучшите логику в «App.render()». – Brandon

+0

@Brandon Это, безусловно, очень надуманный. В моем реальном приложении компонент Message - это несколько уровней иерархии, удаленных из компонента App, и иногда есть 2-3 действия, которые могут запускаться последовательно. Я отправляю ответ, который, как я думаю, касается моих проблем с дизайном. –

ответ

0

Кажется, мои проблемы идут от нарушения пары хорошего React/Flux практики:

  1. Не запускать действия с в магазине
  2. подключать только к Stores в высокоуровневых компонентах

Я рефакторинг, чтобы получить соединения магазина из компонентов низкого уровня. Я не сумасшедший об этом, потому что это означает, что я должен передавать все виды реквизитов через эти глубокие иерархии компонентов, чтобы получить их там, где они должны быть. Но, похоже, это «правильный» способ создания приложения Reflux.

Если никто другой не отправит ответ в течение ближайших нескольких дней, я соглашусь с этим.