React-Native中Navigator的继承问题
最近使用React-Native开发程序,在使用Navigator的时候,发现Navigato无法继承。主要原因:Navigator是通过React.CreateClass创建的,与ES6支持的extends并不能很好地兼容,继承的时候不能覆盖相应的方法。
使用google在 http://www.jianshu.com/p/08d7d9e34957 中找到了解决方法。大致的思路就是在renderScene中对需要覆盖的方法进行重新的赋值。
不过,这样使用方式不太适合复用。于是重新封装成了一个可继承的Navigator。
备注:React-Native 版本为0.39.2
- import React,{Component} from 'react';
- import {
- Navigator
- } from 'react-native';
-
- export default class CanOverrideNavigator extends React.Component {
-
- render() {
- return (
- <Navigator
- {...this.props}
- renderScene={(route,navigator) =>this._renderScene(route,navigator)}
- />);
- }
-
-
- _renderScene(route,navigator) {
- this.overrideMethodFunc(navigator);
- return this.props.renderScene(route,navigator)
- }
-
- //设置继承方法
- overrideMethodFunc(navigator) {
- if (this.overrideMethod) {
- return;
- }
- //保存navigator原有的函数
- this._jumpBack = navigator.jumpBack;
- this._jumpForward = navigator.jumpForward;
- this._jumpTo = navigator.jumpTo;
- this._push = navigator.push;
- this._pop = navigator.pop;
- this._replace = navigator.replace;
- this._replaceAtIndex = navigator.replaceAtIndex;
- this._replacePrevIoUs = navigator.replacePrevIoUs;
- this._resetTo = navigator.resetTo;
- this._immediatelyResetRouteStack = navigator.immediatelyResetRouteStack;
- this._popToRoute = navigator.popToRoute;
- this._popToTop = navigator.popToTop;
- this._getCurrentRoutes = navigator.getCurrentRoutes;
-
- //对navigator的函数进行重新的赋值
- navigator.jumpBack = ()=> {
- this.jumpBack();
- };
- navigator.jumpForward = ()=> {
- this.jumpForward();
- };
- navigator.jumpTo = (route)=> {
- this.jumpTo(route);
- };
- navigator.push = (route)=> {
- this.push(route);
- };
- navigator.pop = ()=> {
- this.pop();
- };
- navigator.replace = (route)=> {
- this.replace(route);
- };
- navigator.replaceAtIndex = (route,index,cb)=> {
- this.replaceAtIndex(route,cb);
- };
- navigator.replacePrevIoUs = (route)=> {
- this.replacePrevIoUs(route);
- };
- navigator.resetTo = (route)=> {
- this.resetTo(route);
- };
- navigator.immediatelyResetRouteStack = (routeStack)=> {
- this.immediatelyResetRouteStack(routeStack);
- };
- navigator.popToRoute = (route)=> {
- this.popToRoute(route);
- };
- navigator.popToTop = ()=> {
- this.popToTop();
- };
- navigator.getCurrentRoutes = ()=> {
- this.getCurrentRoutes();
- };
-
- this.overrideMethod = true;
- }
-
- jumpBack() {
- this._jumpBack();
- }
-
- jumpForward() {
- this._jumpForward();
- }
-
- jumpTo(route) {
- this._jumpTo(route);
- }
-
- push(route) {
- this._push(route);
- }
-
- pop() {
- this._pop();
- }
-
- replace(route) {
- this._replace(route);
- }
-
- replaceAtIndex(route,cb) {
- this._replaceAtIndex(route,cb);
- }
-
- replacePrevIoUs(route) {
- this._replacePrevIoUs(route);
- }
-
- resetTo(route) {
- this._resetTo(route);
- }
-
- immediatelyResetRouteStack(routeStack) {
- this._immediatelyResetRouteStack(routeStack);
- }
-
- popToRoute(route) {
- this._popToRoute(route);
- }
-
- popToTop() {
- this._popToTop();
- }
-
- getCurrentRoutes() {
- return this._getCurrentRoutes();
- }
- }
使用方式
- import React,{Component} from 'react';
- import CanOverrideNavigator from './CanOverrideNavigator';
- import {
- View,Text,TouchableHighlight,Navigator
- } from 'react-native';
-
-
- export default class TestNavigator extends React.Component {
- render() {
- return (
- <MyNavigator
- ref="navigator"
- initialRoute={{component: OneContainer}}
- configureScene={()=> {
- return Navigator.SceneConfigs.PushFromRight;
- }}
- renderScene={this._renderScene.bind(this)}
- />
- );
- }
-
- _renderScene(route,navigator) {
- let Component = route.component;
- return (
- <Component
- navigator={navigator}
- route={route}
- />
- )
- }
- }
-
- class MyNavigator extends CanOverrideNavigator {
- push(rotue) {
- console.log('before push');
- super.push(rotue);
- console.log("after push");
- }
-
- pop() {
- console.log('before pop');
- super.pop();
- console.log("after pop");
- }
- }
-
- class OneContainer extends React.Component {
- render() {
- return (<TouchableHighlight
- style={{padding:20}}
- onPress={()=> {
- this.props.navigator.push({component: TwoContainer})
- }}
- >
- <Text>OneContainer</Text>
- </TouchableHighlight>);
- }
- }
-
- class TwoContainer extends React.Component {
- render() {
- return (<TouchableHighlight
- style={{padding:20}}
- onPress={()=> {
- this.props.navigator.pop()
- }}
- >
- <Text>TwoContainer</Text>
- </TouchableHighlight>);
- }
- }