class实现React继承以及constructor的super的问题
看这篇文章之前 建议先看看阮一峰 的Class继承 便于更好的理解
首先要知道一个问题
React的父子组件和组件类的继承有什么关系?答案是:没有关系
父子组件:指的得是组件标签包含关系 父子组件通过这种关系实现组件通信
组件继承:通过class实现继承关系
es6中class实现的继承
class Father { constructor() { this.name = 'zhangsan' } getDate = (data) => { this.haha() //因为继承关系 所以这个this也指向子组件实例 所以可调用子组件的方法 } getName() { console.log('父组件的name') } } class Son extends Father {//extends相当于继承了父组件的所有属性和方法 constructor(props) { super(props) console.log("this", this) } haha = () => { console.log('子组件的哈哈') } getName = () => { super.getName();//如果不希望自己的getName覆盖父亲组件的getName console.log('子组件的name') } } let son = new Son(); console.log('son 实例', son) son.getDate() //子组件的哈哈 son.getName() //父组件的name 子组件的name
看到上面的代码会发现:
说明Es6里 类里面的this 指向实例对象new Son()
那么问题来啦,请问react组件Son里面的this也是完全等价于实例对象new Son()吗? 答案是否:react组件里this=new Son()实例+React包装
Button父组件:用来给子组件传递props
import React from 'react';
import Son from './son';
function Button() {
return <div>
<Son name='sun sun sun' /> {/*子组件 等价于new Son()+react包裹 */}
</div>
}
export default Button;
Father父组件
import React from 'react'; class Father extends React.Component { constructor(props) { super(props) this.moduleName = 'moduleName'; } getDate = () => { this.haha() } getName() { //不能用做箭头函数 如果是箭头函数则会报错 因为自组件的方法中super.getName()中的super指向的是Father类 如果是箭头函数 指向的是Son的实例对象 console.log('父组件的name') } render() { return 'father' } } export default Father
Son子组件
class Son extends Father{
constructor(props) { super(props); console.log("this", this) } haha = () => { console.log('子组件的哈哈') } getName = () => { super.getName(); console.log('子组件的name') } render() { return <div> <button onClick={this.getName}>点击获取name</button> <button onClick={this.getDate}>点击获取父亲组件的getDate方法</button> </div> } } let son = new Son('我是Son的实例参数') //子组件的哈哈 console.log('Son的实例', son) //父组件的name 子组件的name son.getName() son.getDate() export default Son
所以说:react中的this 等价于 new Son()+React内部方法的集合
那么问题来啦,组件的constructor方法必须要写吗? super必须要加吗?super里面的参数必须要写吗?
1.组件的constructor方法必须要写吗
如果子类没有定义constructor
方法,这个方法会被默认添加,代码如下。也就是说,不管有没有显式定义,任何一个子类都有constructor
方法。
class ColorPoint extends Point { } // 等同于 class ColorPoint extends Point { constructor(...args) { super(...args); } } // 可见没有写constructor,在执行过程中会自动补上
2.如果constructor()方法定义啦 isuper必须要加吗? 答案是:必须要加
3.super()里面的参数必须要写吗? 答案是:可写可不写 如果想要在constructor()里面使用this.props 则需要传递参数
如果子类super() 不传递props/或者传递props constructor(props) { super(); console.log("子类this.props", this.props) } 父亲类别 constructor() { super() console.log("父类this.props", this.props) }
如果子类super()传递props constructor(props) { super(props); console.log("子类this.props", this.props) } 父类super()传递props constructor(props) { super(props) console.log("父类this.props", this.props) }
总结:因为父组件也是继承于 React.Component 所以要想在当前组件里在constructor()里使用this.props 则需要给他的每一层的父组件的super里面加props才能生效值