新手理解Navigator的教程

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

新⼿理解Navigator的教程
注意!从RN 0.43版本开始,官⽅将停⽌维护Navigator,建议⼤家迁移到新的库(⽂档地址需FQ)。

新的导航库⽆论从性能还是易⽤性上都要⼤⼤好于⽼的Navigator!
下⾯是⼀个简单的例⼦,⽤Navigator来跳转页⾯,页⾯之间传递参数 (代码是ES6语法写的):
import React from 'react';
import {
View,
Navigator
} from 'react-native';
import FirstPageComponent from './FirstPageComponent';
export default class SampleComponent extends ponent {
render() {
let defaultName = 'FirstPageComponent';
let defaultComponent = FirstPageComponent;
return (
<Navigator
initialRoute={{ name: defaultName, component: defaultComponent }}
configureScene={(route) => {
return Navigator.SceneConfigs.VerticalDownSwipeJump;
}}
renderScene={(route, navigator) => {
let Component = ponent;
return <Component {...route.params} navigator={navigator} />
}} />
);
}
}
这⾥来解释⼀下代码:
第三⾏: ⼀个初始⾸页的component名字,⽐如我写了⼀个component叫HomeComponent,那么这个name就是这个组件的名字【HomeComponent】了。

第四⾏: 这个组件的Class,⽤来⼀会⼉实例化成 <Component />标签
第七⾏: initialRoute={{ name: defaultName, component: defaultComponent }} 这个指定了默认的页⾯,也就是启动app之后会看到界⾯的第⼀屏。

需要填写两个参数: name 跟 component。

(注意这⾥填什么参数纯粹是⾃定义的,因为这个参数也是你⾃⼰发⾃⼰收,⾃⼰在renderScene⽅法中处理。

我们这⾥⽰例⽤了两个参数,但其实真正使⽤的参数只有component)
第⼋,九,⼗⾏: configureScene={() => {
return Navigator.SceneConfigs.VerticalDownSwipeJump;
}} 这个是页⾯之间跳转时候的动画,具体有哪些?可以看这个⽬录下,有源代码的: node_modules/react-
native/Libraries/CustomComponents/Navigator/NavigatorSceneConfigs.js
最后的⼏⾏: renderScene={(route, navigator) => {
let Component = ponent;
return <Component {...route.params} navigator={navigator} />
}} />
);
这⾥是每个⼈最疑惑的,我们先看到回调⾥的两个参数:route, navigator。

通过打印我们发现route⾥其实就是我们传递的name,component这两个货,navigator是⼀个Navigator的对象,为什么呢,因为它有push pop jump...等⽅法,这是我们等下⽤来跳转页⾯⽤的那个navigator对象。

return <Component {...route.params} navigator={navigator} />
这⾥有⼀个判断,也就是如果传递进来的component存在,那我们就是返回⼀个这个component,结合前⾯ initialRoute 的参数,我们就是知道,这是⼀个会被render出来给⽤户看到的component,然后navigator作为props传递给了这个component。

所以下⼀步,在这个FirstPageComponent⾥⾯,我们可以直接拿到这个 props.navigator:
import React from 'react';
import {
View,
Navigator
} from 'react-native';
import SecondPageComponent from './SecondPageComponent';
export default class FirstPageComponent extends ponent {
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: 'SecondPageComponent',
component: SecondPageComponent,
})
}
}
render() {
return (
<View>
<TouchableOpacity onPress={this._pressButton.bind(this)}>
<Text>点我跳转</Text>
</TouchableOpacity>
</View>
);
}
}
这个⾥⾯创建了⼀个可以点击的区域,让我们点击可以跳到SecondPageComponent这个页⾯,实现页⾯的跳转。

现在来创建SecondPageComponent,并且让它可以再跳回FirstPageComponent:
import React from 'react';
import {
View,
Navigator
} from 'react-native';
import FirstPageComponent from './FirstPageComponent';
export default class SecondPageComponent extends ponent {
constructor(props) {
super(props);
this.state = {};
}
_pressButton() {
const { navigator } = this.props;
if(navigator) {
//很熟悉吧,⼊栈出栈~ 把当前的页⾯pop掉,这⾥就返回到了上⼀个页⾯:FirstPageComponent了
navigator.pop();
}
}
render() {
return (
<View>
<TouchableOpacity onPress={this._pressButton.bind(this)}>
<Text>点我跳回去</Text>
</TouchableOpacity>
</View>
);
}
}
⼤功告成,能进能出了。

关于官⽅⽂档⾥有个东西,这⾥说⼀下:
getCurrentRoutes() - 获取当前栈⾥的路由,也就是push进来,没有pop掉的那些
jumpBack() - 跳回之前的路由,当然前提是保留现在的,还可以再跳回来,会给你保留原样。

jumpForward() - 上⼀个⽅法不是调到之前的路由了么,⽤这个跳回来就好了
jumpTo(route) - Transition to an existing scene without unmounting
push(route) - Navigate forward to a new scene, squashing any scenes that you could jumpForward to
pop() - Transition back and unmount the current scene
replace(route) - Replace the current scene with a new route
replaceAtIndex(route, index) - Replace a scene as specified by an index
replacePrevious(route) - Replace the previous scene
immediatelyResetRouteStack(routeStack) - Reset every scene with an array of routes
popToRoute(route) - Pop to a particular scene, as specified by its route. All scenes after it will be unmounted
popToTop() - Pop to the first scene in the stack, unmounting every other scene
这些都是navigator可以⽤的public method,就是跳转⽤的,⾥⾯有些带参数的XXX(route),新⼿第⼀次看这个⽂档会疑惑,这个route参数是啥呢,这个route就是:
renderScene={(route, navigator) =>
这⾥的route,最基本的route就是:
var route = {
component: LoginComponent
}
这种格式。

这个地⽅有点模糊的,在这⾥先说清楚了。

然后下⾯要讨论,怎么传递参数过去,或者从对⽅获取参数。

传递参数,通过push就可以了。

⽐如在⼀个 press的事件⾥:
//FirstPageComponent.js
import React from 'react';
import {
View,
Navigator
} from 'react-native';
import SecondPageComponent from './SecondPageComponent';
export default class FirstPageComponent extends ponent {
constructor(props) {
super(props);
this.state = {
id: 2
};
}
_pressButton() {
const { navigator } = this.props;
if(navigator) {
navigator.push({
name: 'SecondPageComponent',
component: SecondPageComponent,
//这⾥多出了⼀个 params 其实来⾃于<Navigator ⾥的⼀个⽅法的参数... params: {
id: this.state.id
}
});
}
}
render() {
return (
<View>
<TouchableOpacity onPress={this._pressButton.bind(this)}>
<Text>点我跳转并传递id</Text>
</TouchableOpacity>
</View>
);
}
}
params的来历:
// index.ios.js
<Navigator
initialRoute={{ name: defaultName, component: defaultComponent }}
configureScene={() => {
return Navigator.SceneConfigs.VerticalDownSwipeJump;
}}
renderScene={(route, navigator) => {
let Component = ponent;
if(ponent) {
//这⾥有个 { ...route.params }
return <Component {...route.params} navigator={navigator} />
}
}} />
这个语法是把 routes.params ⾥的每个key 作为props的⼀个属性: navigator.push({
name: 'SecondPageComponent',
component: SecondPageComponent,
params: {
id: this.state.id
}
});
这⾥的就变成了 <Navigator id={} 传递给了下⼀个页⾯。

所以 SecondPageComponent就应该这样取得 id:
//SecondPageComponent.js
import React from 'react';
import {
View,
Navigator
} from 'react-native';
import FirstPageComponent from './FirstPageComponent';
export default class SecondPageComponent extends ponent {
constructor(props) {
super(props);
this.state = {
id: null
}
}
componentDidMount() {
//这⾥获取从FirstPageComponent传递过来的参数: id
this.setState({
id: this.props.id
});
}
_pressButton() {
const { navigator } = this.props;
if(navigator) {
navigator.pop();
}
}
render() {
return (
<View>
<Text>获得的参数: id={ this.state.id }</Text>
<TouchableOpacity onPress={this._pressButton.bind(this)}>
<Text>点我跳回去</Text>
</TouchableOpacity>
</View>
);
}
}
这样在页⾯间传递的参数,就可以获取了。

@sunnylqm 很多⼈不理解这⾥的params,我忍不住稍微补充⼀下。

然后就是返回的时候,也需要传递参数回上⼀个页⾯:
但是navigator.pop()并没有提供参数,因为pop()只是从 [路由1,路由2,路由3。

]⾥把最后⼀个路由踢出去的操作,并不⽀持传递参数给倒数第⼆个路由,这⾥要⽤到⼀个概念,把上⼀个页⾯的实例或者回调⽅法,作为参数传递到当前页⾯来,在当前页⾯操作上⼀个页⾯的state:
这是⼀个查询⽤户信息的例⼦,FirstPageComponent传递id到SecondPageComponent,然后SecondPageComponent返回user信息给FirstPageComponent
//FirstPageComponent.js
import React from 'react';
import {
View,
Navigator
} from 'react-native';
import SecondPageComponent from './SecondPageComponent';
export default class FirstPageComponent extends ponent {
constructor(props) {
super(props);
this.state = {
id: 2,
user: null,
}
}
_pressButton() {
let _this = this;
const { navigator } = this.props;
if(navigator) {
navigator.push({
name: 'SecondPageComponent',
component: SecondPageComponent,
params: {
id: this.state.id,
//从SecondPageComponent获取user
getUser: function(user) {
_this.setState({
user: user
})
}
}
});
}
}
render() {
if( er ) {
return(
<View>
<Text>⽤户信息: { JSON.stringify(er) }</Text> </View>
);
}else {
return(
<View>
<TouchableOpacity onPress={this._pressButton.bind(this)}> <Text>查询ID为{ this.state.id }的⽤户信息</Text>
</TouchableOpacity>
</View>
);
}
}
}
然后再操作SecondPageComponent:
//SecondPageComponent.js
const USER_MODELS = {
1: { name: 'mot', age: 23 },
2: { name: '晴明⼤⼤', age: 25 }
};
import React from 'react';
import {
View,
Navigator
} from 'react-native';
import FirstPageComponent from './FirstPageComponent';
export default class SecondPageComponent extends ponent { 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) {
navigator.pop();
}
}
render() {
return(
<View>
<Text>获得的参数: id={ this.state.id }</Text>
<TouchableOpacity onPress={this._pressButton.bind(this)}> <Text>点我跳回去</Text>
</TouchableOpacity>
</View>
);
}
}
看下效果如何吧。

放个类似的例⼦代码: https:///mozillo/navigation
安装⽅法: npm install && react-native run-android。

相关文档
最新文档