这在以下 github 问题中有所涉及:
https://github.com/facebook/react-native/issues/31
Eric Vicenti 描述 Facebook 如何在内部解决这个问题:
目前最好的方法是在NavigatorIOS 的所有者中创建一个EventEmitter,然后您可以使用route.passProps 将其传递给孩子。孩子可以混入Subscribable.Mixin再混入componentDidMount,就可以了
this.addListenerOn(this.props.events, 'myRightBtnEvent', this._handleRightBtnPress);
很明显,这个 API 需要改进。我们正在积极使用 Relay 中的路由 API,并希望使用 react-router,但我们希望 NavigatorIOS 能够独立使用。也许我们应该在 navigator 对象中添加一个事件发射器,以便子组件可以订阅各种 navigator 活动:
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 mixin,我们唯一需要做的另一件事就是监听myRightBtnEvent 被App 组件触发并将miscFunction 挂接到它。 miscFunction 将从 App 按下处理程序传递虚拟参数,以便我们可以使用它们来设置状态或执行其他操作。
你可以在 RNPlay 上看到这个的工作版本:
https://rnplay.org/apps/H5mMNQ