Это описано в следующем GitHub выпуске:
https://github.com/facebook/react-native/issues/31
Эрик Висенти комментарии, чтобы описать, как Facebook решает эту проблему внутренне:
Currently the best way to do that is to create an EventEmitter
in the owner of the NavigatorIOS
, then you can pass it down to children using route.passProps
. The child can mix in Subscribable.Mixin
and then in componentDidMount
, you can
this.addListenerOn(this.props.events, 'myRightBtnEvent', this._handleRightBtnPress);
It is clear that this API needs improvement. We are actively working the routing API in Relay, and hopefully react-router, but we want NavigatorIOS to be usable independently. Maybe we should add an event emitter inside the navigator object, so child components can subscribe to various navigator activity:
this.addListenerOn(this.props.navigator.events, 'rightButtonPress', this._handleRightBtnPress);
Вот как это выглядит в качестве практического примера:
'use strict';
var React = require('react-native');
var EventEmitter = require('EventEmitter');
var Subscribable = require('Subscribable');
var {
AppRegistry,
StyleSheet,
Text,
View,
NavigatorIOS
} = React;
Сначала мы тянем во всех наших требований, в том числе EventEmitter и Subscribable.
var App = React.createClass({
componentWillMount: function() {
this.eventEmitter = new EventEmitter();
},
onRightButtonPress: function() {
this.eventEmitter.emit('myRightBtnEvent', { someArg: 'argValue' });
},
render: function() {
return <NavigatorIOS
style={styles.container}
initialRoute={{
title: 'Test',
component: Test,
rightButtonTitle: 'Change String',
onRightButtonPress: this.onRightButtonPress,
passProps: {
events: this.eventEmitter
}
}}/>
}
});
В нашей основной компонент верхнего уровня, мы создаем новый EventEmitter (в componentWillMount
) должны быть доступны через компонент, а затем использовать passProps
, чтобы передать ее в Test
компоненте мы указываем для навигатора.
Мы также определяем обработчик для нажатия правой кнопки, который испускает myRightBtnEvent
с некоторыми фиктивными аргументами при нажатии этой кнопки. Теперь, в Test
компонента:
var Test = React.createClass({
mixins: [Subscribable.Mixin],
getInitialState: function() {
return {
variable: 'original string'
};
},
componentDidMount: function() {
this.addListenerOn(this.props.events, 'myRightBtnEvent', this.miscFunction);
},
miscFunction: function(args){
this.setState({
variable: args.someArg
});
},
render: function(){
return(
<View style={styles.scene}><Text>{this.state.variable}</Text></View>
)
}
});
Добавляем Subscribable
подмешать, и единственное, что нам нужно сделать, это слушать вне для myRightBtnEvent
увольняют из App
компонента и подключить miscFunction
к нему. miscFunction
будет передан фиктивные аргументы из обработчика печати App
, поэтому мы можем использовать их для установки состояния или выполнения других действий.
Вы можете увидеть рабочую версию этого на RNPlay:
https://rnplay.org/apps/H5mMNQ
Спасибо за ответ. Я все еще немного любитель, когда речь заходит о реакции на родной язык. Является ли EventEmitter частью реакции-родной уже или мне нужно добавить его? также не знакомы с Subscribable.Mixin –
EventEmitter поставляется с React Native, а Subscribable использует его. Если вы выполните поиск подписок на React Native github, вы увидите несколько примеров, но я попытаюсь сформулировать свой ответ, когда у меня будет больше времени. –
Добавлен полный пример. –