React Native学习之Navigator组件
Navigator组件初探
一个应用往往是由多功能视图组成!多页面的切换:路由或导航
在RN中专门负责视图切换的组件:Navigator
、NavigatorIOS
导航器对比:
Navigator
和NavigatorIOS
都可以用来管理应用中“场景”的导航(也可以称作屏幕)。导航器建立了一个路由栈,用来弹出,推入或者替换路由状态。它们和html5中的history API很类似。主要的区别在于NavigatorIOS使用了iOS中的UINavigationController类,而Navigator则完全用js重写了一个类似功能的React组件。因此Navigator可以兼容iOS和Android,而NavigatorIOS只能用于iOS。
NavigatorIOS:轻量、受限的API设置,使其相对Navigator来说不太方便定制。由开源社区主导开发 —— React Native的官方团队并不在自己的应用中使用。对于大多数正式的App开发,我们建议使用Navigator —— 使用NavigatorIOS实现复杂的需求很容易碰到麻烦。
原理
导航器通过路由对象来分辨不同的场景。利用renderScene方法,导航栏可以根据指定的路由来渲染场景。
可以通过configureScene属性获取指定路由对象的配置信息,从而改变场景的动画或者手势。
class RNAPP extends Component {
render() {
let defaultName='List';
let defaultComponent=List;
return (
<Navigator
initialRoute={{ name: defaultName, component: defaultComponent }}
//配置场景
configureScene = {
(route) => {
//这个是页面之间跳转时候的动画,具体有哪些?可以看这个目录下,有源代码的: node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorSceneConfigs.js
return Navigator.SceneConfigs.VerticalDownSwipeJump;
}
}
renderScene = {
(route, navigator) => {
let Component = route.component;
return <Component {...route.params} navigator={navigator} />
}
}
/>
);
}
}
可以看到回调里的两个参数:route
, navigator
通过打印我们发现route里其实就是我们传递的name,component这两个对象,navigator是一个Navigator的对象,它有push pop jump...等方法,这是我们用来跳转页面用的那个navigator对象。
class List extends Component {
constructor(props) {
super(props);
this.state = {};
}
_pressButton() {
const { navigator } = this.props;
//为什么这里可以取得 props.navigator?请看上文:
//<Component {...route.params} navigator={navigator} />
//这里传递了navigator作为props
if(navigator) {
navigator.push({
name: 'Detail',
component: Detail,
})
}
}
render(){
return (
<ScrollView style={styles.flex}>
<Text style={styles.list_item} onPress={this._pressButton.bind(this)} >☆ 豪华邮轮济州岛3日游</Text>
<Text style={styles.list_item} onPress={this._pressButton.bind(this)}>☆ 豪华邮轮台湾3日游</Text>
<Text style={styles.list_item} onPress={this._pressButton.bind(this)}>☆ 豪华邮轮地中海8日游</Text>
</ScrollView>
);
}
}
这里有一个判断,也就是如果传递进来的component存在,那我们就是返回这个component,结合前面 initialRoute 的参数,我们就是知道,这是一个会被render出来给用户看到的component,然后navigator作为props传递给了这个component。
所以下一步,我们可以直接拿到这个props.navigator
。
源码
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict';
import React, {
AppRegistry,
Component,
StyleSheet,
PixelRatio,
Navigator,
ScrollView,
Text,
View
} from 'react-native';
class RNAPP extends Component {
render() {
let defaultName='List';
let defaultComponent=List;
return (
<Navigator
initialRoute={{ name: defaultName, component: defaultComponent }}
//配置场景
configureScene = {
(route) => {
//页面之间跳转的动画,具体值可以查看源代码: node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorSceneConfigs.js
return Navigator.SceneConfigs.VerticalDownSwipeJump;
}
}
renderScene = {
(route, navigator) => {
let Component = route.component;
return <Component {...route.params} navigator={navigator} />
}
}
/>
);
}
}
class List extends Component {
constructor(props) {
super(props);
this.state = {};
}
_pressButton() {
const { navigator } = this.props;
//为什么这里可以取得 props.navigator?请看上文:
//<Component {...route.params} navigator={navigator} />
//这里传递了navigator作为props
if(navigator) {
navigator.push({
name: 'Detail',
component: Detail,
})
}
}
render(){
return (
<ScrollView style={styles.flex}>
<Text style={styles.list_item} onPress={this._pressButton.bind(this)} >☆ 豪华邮轮济州岛3日游</Text>
<Text style={styles.list_item} onPress={this._pressButton.bind(this)}>☆ 豪华邮轮台湾3日游</Text>
<Text style={styles.list_item} onPress={this._pressButton.bind(this)}>☆ 豪华邮轮地中海8日游</Text>
</ScrollView>
);
}
}
class Detail extends Component{
constructor(props) {
super(props);
this.state = {};
}
_pressButton() {
const { navigator } = this.props;
if(navigator) {
//很熟悉吧,入栈出栈~ 把当前的页面pop掉,即可返回上一个页面
navigator.pop();
}
}
render(){
return(
<ScrollView>
<Text style={styles.list_item} onPress={this._pressButton.bind(this)} >点击我可以跳回去</Text>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
flex:{
flex:1,
},
list_item:{
height:40,
marginLeft:10,
marginRight:10,
fontSize:20,
borderBottomWidth:1,
borderBottomColor:'#ddd',
justifyContent:'center',
},
});
AppRegistry.registerComponent('RNAPP', () => RNAPP);
Navigator参数传递
怎么传递参数过去,或者从对方获取参数。
从列表页跳转至详情页
(1)传递参数,通过push方法。
navigator.push({
name: 'Detail',
component: Detail,
params:{
author: this.state.author,
}
})
这个语法是把routes.params
里的每个 key 作为 props 的一个属性:{...route.params}
(2)提取参数
componentDidMount() {
this.setState({
author:this.props.author,
});
}
(3)使用参数
{this.state.author}
源码:
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict';
import React, {
AppRegistry,
Component,
StyleSheet,
PixelRatio,
Navigator,
ScrollView,
Text,
View
} from 'react-native';
class RNAPP extends Component {
render() {
let defaultName = 'List';
let defaultComponent = List;
return (
<Navigator
initialRoute = {{ name: defaultName, component: defaultComponent }}
//配置场景
configureScene = {
(route) => {
//这个是页面之间跳转时候的动画,具体有哪些?可以看这个目录下,有源代码的: node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorSceneConfigs.js
return Navigator.SceneConfigs.VerticalDownSwipeJump;
}
}
renderScene = {
(route, navigator) => {
let Component = route.component;
return <Component {...route.params} navigator={navigator} />
}
}
/>
);
}
}
class List extends Component {
constructor(props) {
super(props);
this.state = {
author:'rnapp.cc'
};
}
_pressButton() {
const { navigator } = this.props;
//为什么这里可以取得 props.navigator?请看上文:
//<Component {...route.params} navigator={navigator} />
//这里传递了navigator作为props
if (navigator) {
navigator.push({
name: 'Detail',
component: Detail,
params:{
author: this.state.author,
}
})
}
}
render(){
return (
<ScrollView style={styles.flex}>
<Text style={styles.list_item} onPress={this._pressButton.bind(this)} >☆ 豪华邮轮济州岛3日游</Text>
<Text style={styles.list_item} onPress={this._pressButton.bind(this)}>☆ 豪华邮轮台湾3日游</Text>
<Text style={styles.list_item} onPress={this._pressButton.bind(this)}>☆ 豪华邮轮地中海8日游</Text>
</ScrollView>
);
}
}
class Detail extends Component{
constructor(props) {
super(props);
this.state = {};
}
componentDidMount() {
this.setState({
author:this.props.author,
});
}
_pressButton() {
const { navigator } = this.props;
if(navigator) {
//很熟悉吧,入栈出栈~ 把当前的页面pop掉,即可返回上一个页面
navigator.pop();
}
}
render() {
return(
<ScrollView>
<Text style={styles.list_item} onPress={this._pressButton.bind(this)} >作者是:{this.state.author}</Text>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
flex:{
flex:1,
},
list_item:{
height:40,
marginLeft:10,
marginRight:10,
fontSize:20,
borderBottomWidth:1,
borderBottomColor:'#ddd',
justifyContent:'center',
},
});
AppRegistry.registerComponent('RNAPP', () => RNAPP);
从详情页返回至列表页
综合实例:从列表页传递用户id给详情页,详情页跟进用户id查询用户信息,并把
用户信息回传给列表页显示出来
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict';
import React, {
AppRegistry,
Component,
StyleSheet,
PixelRatio,
Navigator,
ScrollView,
Text,
View
} from 'react-native';
class RNAPP extends Component {
render() {
let defaultName='List';
let defaultComponent=List;
return (
<Navigator
initialRoute = {{ name: defaultName, component: defaultComponent }}
//配置场景
configureScene = {
(route) => {
//这个是页面之间跳转时候的动画,具体有哪些?可以看这个目录下,有源代码的: node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorSceneConfigs.js
return Navigator.SceneConfigs.VerticalUpSwipeJump;
}
}
renderScene = {
(route, navigator) => {
let Component = route.component;
return <Component {...route.params} navigator={navigator} />
}
}
/>
);
}
}
class List extends Component {
constructor(props) {
super(props);
this.state = {
id:1,
user:null,
};
}
_pressButton() {
const { navigator } = this.props;
//为什么这里可以取得 props.navigator?请看上文:
//<Component {...route.params} navigator={navigator} />
//这里传递了navigator作为props
const self = this;
if (navigator) {
navigator.push({
name: 'Detail',
component: Detail,
params:{
id: this.state.id,
//从详情页获取user
getUser: function(user) {
self.setState({
user: user
})
},
}
})
}
}
render() {
if (this.state.user) {
return(
<View>
<Text style={styles.list_item}>用户信息: { JSON.stringify(this.state.user) }</Text>
</View>
);
} else {
return (
<ScrollView style={styles.flex}>
<Text style={styles.list_item} onPress={this._pressButton.bind(this)} >☆ 豪华邮轮济州岛3日游</Text>
<Text style={styles.list_item} onPress={this._pressButton.bind(this)}>☆ 豪华邮轮台湾3日游</Text>
<Text style={styles.list_item} onPress={this._pressButton.bind(this)}>☆ 豪华邮轮地中海8日游</Text>
</ScrollView>
);
}
}
}
const USER_MODELS = {
1: { name: '张三', age: 23 },
2: { name: '李四', age: 25 }
};
class Detail extends Component {
constructor(props) {
super(props);
this.state = {
id: null
};
}
componentDidMount() {
//这里获取从FirstPageComponent传递过来的参数: id
this.setState({
id: this.props.id
});
}
_pressButton() {
const { navigator } = this.props;
if (this.props.getUser) {
let user = USER_MODELS[this.props.id];
this.props.getUser(user);
}
if (navigator) {
//很熟悉吧,入栈出栈~ 把当前的页面pop掉,即可返回上一个页面
navigator.pop();
}
}
render() {
return(
<ScrollView>
<Text style={styles.list_item} >传递过来的用户id是:{this.state.id}</Text>
<Text style={styles.list_item} onPress={this._pressButton.bind(this)} >点击我可以跳回去</Text>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
flex:{
flex:1,
},
list_item:{
height:40,
marginLeft:10,
marginRight:10,
fontSize:20,
borderBottomWidth:1,
borderBottomColor:'#ddd',
justifyContent:'center',
},
});
AppRegistry.registerComponent('RNAPP', () => RNAPP);
版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/02/25/react-native-learning-navigator-component/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论