React-Native中类的继承和model的继承
1.类的继承(ES6)
其实,在React-Native开发中时常会遇到一些方法重复的写,想像Java一样解耦出来呢,又觉得这些方法与类的关联性又很高,不单独提出来,代码有很冗余。其实在ES6中的继承跟Java中的继承也大同小异,这给编程也带来了很多便捷!
-
定义
面向对象软件技术当中的一个概念。如果一个类A“继承自”另一个类B,就把这个A称为“B的子类”,而把B称为“A的父类”也可以称“B是A的超类”。继承可以使得子类别具有父类别的各种属性和方法,而不需要再次编写相同的代码。在令子类继承父类的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类的原有属性和方法,使其获得与父类不同的功能。另外,为子类追加新的属性和方法也是常见的做法 -
extends关键字
在React-Native开发中采用extends关键字实现继承,即 AClass extends BClass即可,例如:
定义一个父类BaseClassexport default class BaseClass{ }
定义一个子类ChildClass继承父类
export default class ChildClass extends BaseClass{ }
其实,在React-Native中最常见的是Component继承,即 class BaseComponent extends Component,这种对于多个相同相似的界面可以节约很多时间,例如:
定义一个父类BaseComponent
import { Component } from 'react' class BaseComponent extends Component { } export default BaseComponent
定义一个子类ChildComponent
import { BaseComponent } from '组件路径' class ChildComponent extends BaseComponent { } export default BaseComponent
如果你用到了constructor就必须写super(),是用来初始化this的,可以绑定事件到this上;
如果你在constructor中要使用this.props,就必须给super加参数:super(props);
无论有没有constructor,在render中this.props都是可以使用的,这是React自动附带的
如果没用到constructor,是可以不写的;React会默认添加一个空的constructor。 -
属性
子类调用通过 this.属性名 调用- 属性定义在类外是不可被继承的,例如:
import { Component } from 'react' const a = "定义在这里不能被子类继承" class BaseComponent extends Component { } export default BaseComponent
- 在类里直接定义属性不可使用关键字声明,例如:
import { Component } from 'react' class BaseComponent extends Component { var a = 1 //这样写不可取 let b = 2 //这样写不可取 c = 3 //这样写可被子类继承,通过this.c使用 } export default BaseComponent
-
声明在方法中的属性不可通过this调用
-
在React-Native开发中,一般都是定义在state中,即
this.state = { a:"属性值" }
调用的时候通过this.state.a调用,这样a的值一旦改变,调用的地方的值也会跟到改变,且定义在constructor中,参考如下:
import { Component } from 'react' class BaseComponent extends Component { constructor(props){ super(props) this.state = { a:"属性值" } } } export default BaseComponent
- 在子类中如果也定义了state,子类的state将会覆盖父类的state,如果既想要父类state中的属性,也想定义子类的私有属性,可使用...语法,即:
在子类的constructor中声明
constructor(props){ super(props) this.state = { ...this.state,//共用父类属性 b:"子类私有属性" } }
-
方法
- 子类的方法可完全覆盖父类的方法
在父类定义一个方法叫 func:
import { Component } from 'react' class BaseComponent extends Component { constructor(props){ super(props) this.state = { text:"默认值" } } func(){ this.setState({ text:"父类修改func的值" }) } } export default BaseComponent
在子类也定义一个方法叫 func:
import { BaseComponent } from '组件路径' class ChildComponent extends BaseComponent { func(){ this.setState({ text:"子类修改func的值" }) } } export default BaseComponent
注:子类func方法将会完全覆盖父类方法,父类中的方法不会被执行,只会执行子类的func方法
显示顺序:默认值->子类修改func的值
- 保留父类方法中的逻辑,子类应写为:
import { BaseComponent } from '组件路径' class ChildComponent extends BaseComponent { func(){ super.func() this.setState({ text:"子类修改func的值" }) } } export default BaseComponent
这样既先调用父类的func方法,在执行子类func方法
显示顺序:默认值->父类修改func的值->子类修改func的值- 同名方法后者会覆盖前者,即使传递的参数个数不同,这里与Java中的重载不同
import { BaseComponent } from '组件路径' class ChildComponent extends BaseComponent { func(){ this.setState({ text:"子类修改func的值" }) } func(text) { this.setState({ text: text }) } } export default BaseComponent
子类func()方法将会覆盖父类中的func()方法,子类的func(text)方法将会覆盖子类的func()方法,即遵循同名方法后者覆盖前者同名方法,不管是否有参数!如果强行调用func()方法,也会去调用func(text)这个方法,参数text值为undefined
2.model的继承
model的继承需要用到第三方,这里主要介绍dva-model-extend:https://github.com/dvajs/dva-model-extend,按照dva-model-extend文档所说配置即可:
- 添加依赖
npm install --save dva-model-extend
- API说明
modelExtend(...models) => Model
model.namespace:命名空间将由子类覆盖父类命名空间
model[state|subscriptions|effects|reducers]:将会被合并
model.state:如果不是对象将会被子类覆盖 - 使用举例:
父model代码
子model代码export default { namespace: 'parentModel', state: { parentText: '父参数', text: '一个父文本参数' }, reducers: { updateState(state, { payload }) { return { ...state, ...payload } } }, effects: { *test({ payload }, { call, put }) { console.log('父test方法') }, *test1({ payload }, { call, put }) { console.log('父test1方法') } }, subscriptions: {} }
import modelExtend from 'dva-model-extend' import parentModel from '父model的路径' export default modelExtend(parentModel, { namespace: 'childModel', state: { childText: '子参数', text: '一个子文本参数' }, reducers: {}, effects: { *childTest({ payload }, { call, put }) { console.log('子childTest方法') }, *test1({ payload }, { call, put }) { console.log('子test1方法') } }, subscriptions: { } })
文中用到的第三方model继承:https://github.com/dvajs/dva-model-extend
介绍一个特好用的react-native开发框架:https://github.com/nihgwu/react-native-dva-starter