在导航器弹出窗口上反应 Native Pass 属性
React Native Pass properties on navigator pop
我在我的 React 本机应用程序上使用 NavigatorIOS。我想在导航回上一条路线时传递一些属性。
一个例子:
我在表单页面中。提交数据后,想回到之前的路由,根据提交的数据做一些事情
我该怎么做?
当你推送新路由并在弹出到上一个路由之前用表单数据调用它时,你能在导航器道具上传递一个回调函数吗?
显示如何在弹出之前使用回调的代码示例。这是专门针对 Navigator 而不是 NavigatorIOS 的,但也可以应用类似的代码。
您有第 1 页和第 2 页。您正在从第 1 页推送到第 2 页,然后弹回到第 1 页。您需要从 Page2 传递一个回调函数,它会触发 Page1 中的一些代码,然后才会弹出回 Page1。
第 1 页 -
_goToPage2: function() {
this.props.navigator.push({
component: Page2,
sceneConfig: Navigator.SceneConfigs.FloatFromBottom,
title: 'hey',
callback: this.callbackFunction,
})
},
callbackFunction: function(args) {
//do something
console.log(args)
},
第 2 页 -
_backToPage1: function() {
this.props.route.callback(args);
this.props.navigator.pop();
},
函数 "callbackFunction" 将在 "pop" 之前调用。对于 NavigatorIOS,您应该在 "passProps" 中执行相同的回调。您还可以将 args 传递给此回调。希望对你有帮助。
对于 NavigatorIOS,您还可以使用 replacePreviousAndPop()。
代码:
'use strict';
var React = require('react-native');
var {
StyleSheet,
Text,
TouchableOpacity,
View,
AppRegistry,
NavigatorIOS
} = React;
var MainApp = React.createClass({
render: function() {
return (
<NavigatorIOS
style={styles.mainContainer}
initialRoute={{
component: FirstScreen,
title: 'First Screen',
passProps: { text: ' ...' },
}}
/>
);
},
});
var FirstScreen = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text style={styles.helloText}>
Hello {this.props.text}
</Text>
<TouchableOpacity
style={styles.changeButton} onPress={this.gotoSecondScreen}>
<Text>Click to change</Text>
</TouchableOpacity>
</View>
);
},
gotoSecondScreen: function() {
console.log("button pressed");
this.props.navigator.push({
title: "Second Screen",
component: SecondScreen
});
},
});
var SecondScreen = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text style={styles.helloText}>
Select a greeting
</Text>
<TouchableOpacity
style={styles.changeButton} onPress={() => this.sayHello("World!")}>
<Text>...World!</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.changeButton} onPress={() => this.sayHello("my Friend!")}>
<Text>...my Friend!</Text>
</TouchableOpacity>
</View>
);
},
sayHello: function(greeting) {
console.log("world button pressed");
this.props.navigator.replacePreviousAndPop({
title: "First Screen",
component: FirstScreen,
passProps: {text: greeting}
});
}
});
var styles = StyleSheet.create({
mainContainer: {
flex: 1,
backgroundColor: "#eee"
},
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
marginTop: 50,
},
helloText: {
fontSize: 16,
},
changeButton: {
padding: 5,
borderWidth: 1,
borderColor: "blue",
borderRadius: 4,
marginTop: 20
}
});
AppRegistry.registerComponent("TestApp", () => MainApp);
您可以在此处找到工作示例:https://rnplay.org/apps/JPWaPQ
希望对您有所帮助!
我在 React Native 的导航器中遇到了同样的问题,我设法使用 EventEmitters 和 Subscribables 解决了这个问题。这里的这个例子真的很有帮助:https://colinramsay.co.uk/2015/07/04/react-native-eventemitters.html
我需要做的就是更新 ES6 和最新版本的 React Native。
应用程序的顶级:
import React, { Component } from 'react';
import {AppRegistry} from 'react-native';
import {MyNavigator} from './components/MyNavigator';
import EventEmitter from 'EventEmitter';
import Subscribable from 'Subscribable';
class MyApp extends Component {
constructor(props) {
super(props);
}
componentWillMount() {
this.eventEmitter = new EventEmitter();
}
render() {
return (<MyNavigator events={this.eventEmitter}/>);
}
}
AppRegistry.registerComponent('MyApp', () => MyApp);
在导航器的 _renderScene 函数中,确保包含 "events" 属性:
_renderScene(route, navigator) {
var Component = route.component;
return (
<Component {...route.props} navigator={navigator} route={route} events={this.props.events} />
);
}
这里是呈现列表视图的 FooScreen 组件的代码。
(请注意 react-mixin was used here in order to subscribe to the event. In most cases mixins should be eschewed 支持高阶组件,但在这种情况下我找不到解决方法):
import React, { Component } from 'react';
import {
StyleSheet,
View,
ListView,
Text
} from 'react-native';
import {ListItemForFoo} from './ListItemForFoo';
import reactMixin from 'react-mixin'
import Subscribable from 'Subscribable';
export class FooScreen extends Component {
constructor(props) {
super(props);
this._refreshData = this._refreshData.bind(this);
this._renderRow = this._renderRow.bind(this);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows([])
}
}
componentDidMount(){
//This is the code that listens for a "FooSaved" event.
this.addListenerOn(this.props.events, 'FooSaved', this._refreshData);
this._refreshData();
}
_refreshData(){
this.setState({
dataSource: this.state.dataSource.cloneWithRows(//YOUR DATASOURCE GOES HERE)
})
}
_renderRow(rowData){
return <ListItemForFoo
foo={rowData}
navigator={this.props.navigator} />;
}
render(){
return(
<ListView
dataSource={this.state.dataSource}
renderRow={this._renderRow}
/>
)
}
}
reactMixin(FooScreen.prototype, Subscribable.Mixin);
终于。我们需要在保存 Foo 后实际发出该事件:
在您的 NewFooForm.js 组件中,您应该有一个像这样的方法:
_onPressButton(){
//Some code that saves your Foo
this.props.events.emit('FooSaved'); //emit the event
this.props.navigator.pop(); //Pop back to your ListView component
}
您可以使用 AsyncStorage,在子组件上保存一些值,然后调用 navigator.pop():
AsyncStorage.setItem('postsReload','true');
this.props.navigator.pop();
在父组件中,您可以从 AsyncStorage 读取它:
async componentWillReceiveProps(nextProps) {
const reload = await AsyncStorage.getItem('postsReload');
if (reload && reload=='true')
{
AsyncStorage.setItem('postsReload','false');
//do something
}
}
这是一个老问题,但目前 Passing params to a previous screen 的 React Navigation 文档建议我们使用 navigation.navigate() 并传递我们希望上一个屏幕具有的任何参数。
我在我的 React 本机应用程序上使用 NavigatorIOS。我想在导航回上一条路线时传递一些属性。
一个例子: 我在表单页面中。提交数据后,想回到之前的路由,根据提交的数据做一些事情
我该怎么做?
当你推送新路由并在弹出到上一个路由之前用表单数据调用它时,你能在导航器道具上传递一个回调函数吗?
显示如何在弹出之前使用回调的代码示例。这是专门针对 Navigator 而不是 NavigatorIOS 的,但也可以应用类似的代码。
您有第 1 页和第 2 页。您正在从第 1 页推送到第 2 页,然后弹回到第 1 页。您需要从 Page2 传递一个回调函数,它会触发 Page1 中的一些代码,然后才会弹出回 Page1。
第 1 页 -
_goToPage2: function() {
this.props.navigator.push({
component: Page2,
sceneConfig: Navigator.SceneConfigs.FloatFromBottom,
title: 'hey',
callback: this.callbackFunction,
})
},
callbackFunction: function(args) {
//do something
console.log(args)
},
第 2 页 -
_backToPage1: function() {
this.props.route.callback(args);
this.props.navigator.pop();
},
函数 "callbackFunction" 将在 "pop" 之前调用。对于 NavigatorIOS,您应该在 "passProps" 中执行相同的回调。您还可以将 args 传递给此回调。希望对你有帮助。
对于 NavigatorIOS,您还可以使用 replacePreviousAndPop()。
代码:
'use strict';
var React = require('react-native');
var {
StyleSheet,
Text,
TouchableOpacity,
View,
AppRegistry,
NavigatorIOS
} = React;
var MainApp = React.createClass({
render: function() {
return (
<NavigatorIOS
style={styles.mainContainer}
initialRoute={{
component: FirstScreen,
title: 'First Screen',
passProps: { text: ' ...' },
}}
/>
);
},
});
var FirstScreen = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text style={styles.helloText}>
Hello {this.props.text}
</Text>
<TouchableOpacity
style={styles.changeButton} onPress={this.gotoSecondScreen}>
<Text>Click to change</Text>
</TouchableOpacity>
</View>
);
},
gotoSecondScreen: function() {
console.log("button pressed");
this.props.navigator.push({
title: "Second Screen",
component: SecondScreen
});
},
});
var SecondScreen = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text style={styles.helloText}>
Select a greeting
</Text>
<TouchableOpacity
style={styles.changeButton} onPress={() => this.sayHello("World!")}>
<Text>...World!</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.changeButton} onPress={() => this.sayHello("my Friend!")}>
<Text>...my Friend!</Text>
</TouchableOpacity>
</View>
);
},
sayHello: function(greeting) {
console.log("world button pressed");
this.props.navigator.replacePreviousAndPop({
title: "First Screen",
component: FirstScreen,
passProps: {text: greeting}
});
}
});
var styles = StyleSheet.create({
mainContainer: {
flex: 1,
backgroundColor: "#eee"
},
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
marginTop: 50,
},
helloText: {
fontSize: 16,
},
changeButton: {
padding: 5,
borderWidth: 1,
borderColor: "blue",
borderRadius: 4,
marginTop: 20
}
});
AppRegistry.registerComponent("TestApp", () => MainApp);
您可以在此处找到工作示例:https://rnplay.org/apps/JPWaPQ
希望对您有所帮助!
我在 React Native 的导航器中遇到了同样的问题,我设法使用 EventEmitters 和 Subscribables 解决了这个问题。这里的这个例子真的很有帮助:https://colinramsay.co.uk/2015/07/04/react-native-eventemitters.html
我需要做的就是更新 ES6 和最新版本的 React Native。
应用程序的顶级:
import React, { Component } from 'react';
import {AppRegistry} from 'react-native';
import {MyNavigator} from './components/MyNavigator';
import EventEmitter from 'EventEmitter';
import Subscribable from 'Subscribable';
class MyApp extends Component {
constructor(props) {
super(props);
}
componentWillMount() {
this.eventEmitter = new EventEmitter();
}
render() {
return (<MyNavigator events={this.eventEmitter}/>);
}
}
AppRegistry.registerComponent('MyApp', () => MyApp);
在导航器的 _renderScene 函数中,确保包含 "events" 属性:
_renderScene(route, navigator) {
var Component = route.component;
return (
<Component {...route.props} navigator={navigator} route={route} events={this.props.events} />
);
}
这里是呈现列表视图的 FooScreen 组件的代码。
(请注意 react-mixin was used here in order to subscribe to the event. In most cases mixins should be eschewed 支持高阶组件,但在这种情况下我找不到解决方法):
import React, { Component } from 'react';
import {
StyleSheet,
View,
ListView,
Text
} from 'react-native';
import {ListItemForFoo} from './ListItemForFoo';
import reactMixin from 'react-mixin'
import Subscribable from 'Subscribable';
export class FooScreen extends Component {
constructor(props) {
super(props);
this._refreshData = this._refreshData.bind(this);
this._renderRow = this._renderRow.bind(this);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows([])
}
}
componentDidMount(){
//This is the code that listens for a "FooSaved" event.
this.addListenerOn(this.props.events, 'FooSaved', this._refreshData);
this._refreshData();
}
_refreshData(){
this.setState({
dataSource: this.state.dataSource.cloneWithRows(//YOUR DATASOURCE GOES HERE)
})
}
_renderRow(rowData){
return <ListItemForFoo
foo={rowData}
navigator={this.props.navigator} />;
}
render(){
return(
<ListView
dataSource={this.state.dataSource}
renderRow={this._renderRow}
/>
)
}
}
reactMixin(FooScreen.prototype, Subscribable.Mixin);
终于。我们需要在保存 Foo 后实际发出该事件:
在您的 NewFooForm.js 组件中,您应该有一个像这样的方法:
_onPressButton(){
//Some code that saves your Foo
this.props.events.emit('FooSaved'); //emit the event
this.props.navigator.pop(); //Pop back to your ListView component
}
您可以使用 AsyncStorage,在子组件上保存一些值,然后调用 navigator.pop():
AsyncStorage.setItem('postsReload','true');
this.props.navigator.pop();
在父组件中,您可以从 AsyncStorage 读取它:
async componentWillReceiveProps(nextProps) {
const reload = await AsyncStorage.getItem('postsReload');
if (reload && reload=='true')
{
AsyncStorage.setItem('postsReload','false');
//do something
}
}
这是一个老问题,但目前 Passing params to a previous screen 的 React Navigation 文档建议我们使用 navigation.navigate() 并传递我们希望上一个屏幕具有的任何参数。