React Native - 从 NavigatorIOS 调用子函数
React Native - Call Function of child from NavigatorIOS
我正在尝试从父导航器上的右键调用子函数。
我需要的基本代码示例如下:
Main.js
<NavigatorIOS
style={styles.container}
initialRoute={{
title: 'Test',
component: Test,
rightButtonTitle: 'Change String',
onRightButtonPress: () => ***I Want to call miscFunction from here*** ,
passProps: {
FBId: this.state.fbidProp,
favsPage: true
}
}}/>
Test.js
class Test extends React.Component{
constructor(props){
super(props);
this.state = {
variable: 'some string'
};
}
miscFunction(){
this.setState({
variable: 'new string'
};
}
render(){
return(
<Text> {variable} </Text>
)
}
}
这在以下 github 问题中有所介绍:
https://github.com/facebook/react-native/issues/31
Eric Vicenti 评论描述 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
mixin,我们唯一需要做的另一件事就是监听 App
组件触发的 myRightBtnEvent
并挂钩 miscFunction
到此为止。 miscFunction
将从 App
新闻处理程序传递虚拟参数,因此我们可以使用它们来设置状态或执行其他操作。
你可以在 RNPlay 上看到这个的工作版本:
一个。在初始组件中
this.props.navigator.push({
title: 'title',
component: MyComponent,
rightButtonTitle: 'rightButton',
passProps: {
ref: (component) => {this.pushedComponent = component},
},
onRightButtonPress: () => {
// call func
this.pushedComponent && this.pushedComponent.myFunc();
},
});
乙。在推送组件中
替换推送组件中的 onRightButtonPress 函数。
componentDidMount: function() {
// get current route
var route = this.props.navigator.navigationContext.currentRoute;
// update onRightButtonPress func
route.onRightButtonPress = () => {
// call func in pushed component
this.myFunc();
};
// component will not rerender
this.props.navigator.replace(route);
},
您可以使用 flux, here is a demo: https://github.com/backslash112/react-native_flux_demo
我正在尝试从父导航器上的右键调用子函数。
我需要的基本代码示例如下:
Main.js
<NavigatorIOS
style={styles.container}
initialRoute={{
title: 'Test',
component: Test,
rightButtonTitle: 'Change String',
onRightButtonPress: () => ***I Want to call miscFunction from here*** ,
passProps: {
FBId: this.state.fbidProp,
favsPage: true
}
}}/>
Test.js
class Test extends React.Component{
constructor(props){
super(props);
this.state = {
variable: 'some string'
};
}
miscFunction(){
this.setState({
variable: 'new string'
};
}
render(){
return(
<Text> {variable} </Text>
)
}
}
这在以下 github 问题中有所介绍:
https://github.com/facebook/react-native/issues/31
Eric Vicenti 评论描述 Facebook 如何在内部解决这个问题:
Currently the best way to do that is to create an
EventEmitter
in the owner of theNavigatorIOS
, then you can pass it down to children usingroute.passProps
. The child can mix inSubscribable.Mixin
and then incomponentDidMount
, you canthis.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
mixin,我们唯一需要做的另一件事就是监听 App
组件触发的 myRightBtnEvent
并挂钩 miscFunction
到此为止。 miscFunction
将从 App
新闻处理程序传递虚拟参数,因此我们可以使用它们来设置状态或执行其他操作。
你可以在 RNPlay 上看到这个的工作版本:
一个。在初始组件中
this.props.navigator.push({
title: 'title',
component: MyComponent,
rightButtonTitle: 'rightButton',
passProps: {
ref: (component) => {this.pushedComponent = component},
},
onRightButtonPress: () => {
// call func
this.pushedComponent && this.pushedComponent.myFunc();
},
});
乙。在推送组件中
替换推送组件中的 onRightButtonPress 函数。
componentDidMount: function() {
// get current route
var route = this.props.navigator.navigationContext.currentRoute;
// update onRightButtonPress func
route.onRightButtonPress = () => {
// call func in pushed component
this.myFunc();
};
// component will not rerender
this.props.navigator.replace(route);
},
您可以使用 flux, here is a demo: https://github.com/backslash112/react-native_flux_demo