2016-08-05 5 views
2

Я в разгар применения приложения реального времени в ReactJS для мониторинга датчиков. Я использую AutobahnJS + Websockets на PHP для потоковой передачи данных.ReactJS: Передача реквизитов

Это абстракция моей приборной панели в виде компонентов. Abstraction of dashboard in component view

Main.jsx:

class Main extends React.Component { 
constructor(props) { 
    super(props) 
} 

componentDidMount() { 
    $(document).foundation(); 

    var that = this; 

    var conn = new ab.Session('ws://xx.xxx.xxx.xx', function() { 
     conn.subscribe('', function(topic, data) { 
      console.log(data); 
      that.setState({ 
       result: data 
      }); 
     }); 
    }, function() { 
     console.warn('WebSocket connection closed'); 
    }, {'skipSubprotocolCheck': true}); 
} 
render() { 

    return (
     <div> 
      <div className="off-canvas-wrapper"> 
       <div className="off-canvas-wrapper-inner" data-off-canvas-wrapper> 
        <div className="off-canvas position-right" data-position="right" id="offCanvas" data-off-canvas> 
         <SensorDetails/> 
        </div> 

        <div className="off-canvas-content" data-off-canvas-content> 
         <Nav/> 

         <div className="row"> 
          <div className="columns medium-12 large 12"> 
           {this.props.children} 
          </div> 
         </div> 
        </div> 
       </div> 
      </div> 
     </div> 
    ); 
} 
}; 

module.exports = Main; 

Что такое правильный способ передать реквизит из Main.jsx в BuildingList.jsx? Я попытался заменить:

{this.props.children} 

с

<Dashboard data={this.state.result}/> 

Это работает, но я не в состоянии получить доступ к ссылкам, например, Настройки аккаунта. Мой реактивный маршрутизатор настроен как таковой:

<Router history={hashHistory}> 
    <Route path="/dashboard" component={Main} > 
     <Route path="/about" component={About} onEnter={requireLogin}/> 
     <Route path="/examples" component={Examples} onEnter={requireLogin}/> 
     <Route path="/accountSettings" component={AccountSettings} onEnter={requireLogin}/> 
     <IndexRoute component={Dashboard}/> 
    </Route> 
    <Route path="/" component={Login} onEnter={redirectIfLoggedIn}/> 
</Router> 

Как исправить эту проблему? Благодарю.

ответ

1

Ну, React предназначен для передачи реквизита сверху вниз ..

Это делает Data-Management очень трудно, потому что вы можете иметь много компонентов, в которых нуждается одни и те же данные.

Таким образом, лучше использовать какую-либо архитектуру потока (например, Redux) Или более простой Data Layer, такой как Mobx.

Вы должны взглянуть на каждый, потому что они очень разные, но разработаны, чтобы помочь вам в управлении данными, (специально) в React

3

Есть несколько способов справиться с этим.

Один из способов, который вы можете использовать, - это сделать ваши дети внутри Main.jsx таким же. Передача двух реквизитов вашим детям (state и updateState).

{React.Children.map(this.props.children, (child) => { 
    return React.cloneElement(child, { 
     state: this.state, 
     updateState: (state) => this.setState(state) 
    }); 
}} 

С вашего дочернего компонента вы можете обновить состояние Main.jsx, вызвав это.

this.props.updateState({prop: 'value'}) 

Я не думаю, что это лучший способ сделать что-то в Реагировании. Я предпочитаю использовать подход к событиям. У меня обычно есть что-то вроде следующего, чтобы прослушать и обновить «глобально доступное состояние».

Внутри Main.jsx

componentDidMount() { 
    App.Event.on('state.update', (state = {}) => this.setState(state)); 
} 

App.Event простая система событий, которые вы можете вызвать запуская события, как это.

App.Event.fire('state.change', {prop: 'value'}); 
+0

Thanks Enjijar! Я пробовал оба решения, но ни один из них не работает. Для второго решения я получаю ошибку «Приложение не определено». –