React中类定义组件constructor 和super

刚开始学习React没多久,在老师的教程里看到了类组件的使用示例,但是和资料上有些冲突,而引发了一些疑问:

  • 类组件中到底要不要定义构造函数constructor()?
  • super()里边到底要不要传入props参数?
  • 绑定事件到底要不要在构造函数constructor()中进行?

查找资料,总结如下:

类组件:

定义组件可以使用函数定义组件和类定义组件()   (推荐一篇随笔,创建组件的三种方式: https://www.cnblogs.com/wonyun/p/5930333.html

简单说一下  函数定义组件和类定义组件的区别:

  • 函数组件中无法使用state,也无法使用组件的生命周期方法;
  • 函数组件都是展示性组件,接受props,渲染DOM;
  • 函数组件中没有this,但在类组件中仍要绑定this这个琐碎的事,如:在render()方法中要使用this.props来替换props;
  • 类组件中可以使用局部状态state和生命周期方法。

类定义组件实例:

class GreetingInput extends React.Component{
//构造函数
    constructor(props){
        super(props);//将props传入到构造方法中
        this.state={name:"Tom"};//初始化state的值
        this.switchName=this.switchName.bind(this);
    }
//自定义的switchName方法,用作事件处理
    switchName(){
       if(this.state.name==="Tom"){
          this.setState({name:"Jerry"});//修改state的值
        }else{
          this.setState({name:"Tom"});
        }
   }
//render方法  渲染在UI上的内容
   render(){
      return(
        <div>
          <h1>hello,{this.state.name}</h1>
          <button onClick={this.switchName}>{this.state.name==="Tom"? "Jerry":"Tom"}</button>
        </div>
      );
   }

}   

ReactDOM.render(
  <GreetingInput/>,document.getElementById("root")
);

问题一:类组件中到底要不要定义构造函数constructor()?

ES6中新增了类的概念,一个类必须要有constructor方法,如果在类中没有显示定义,则一个空的constructor方法会被默认添加;

一般需要在构造函数中初始化state和绑定事件,因此当需要初始化state或绑定事件时,需要显示定义constructor方法,并在constructor方法中初始化state和绑定事件

问题二:super()里边到底要不要传入props参数?

首先说明一点,若显示声明了constructor方法,则必须要调用super,即仅当存在constructor方法时,必须调用super

又是遇到一些示例中super()中没有传入参数props,super()和super(props)到底该怎么使用?

React会自行将props设置在组件中的 除了constructor方法 的任何地方  因此在组件的 非constructor方法中  使用props时,可不用传入,直接使用,

当想要在constructor内使用props,则必须要将props传入super中,这样才能在constructor中访问到props,否则可以不用传入。

问题三:绑定事件到底要不要在构造函数constructor()中进行?

前面说了一般需要在构造函数中绑定事件,但需要使用bind,如果不想调用bind,也可以使用以下方法:

1、使用箭头函数初始化方法,则上边的例子就变为:

class GreetingInput extends React.Component{
//构造函数方法
    constructor(props){
        super(props);
        this.state={name:"Tom"};
        
    }
//自定义的switchName方法,用作事件处理   下边用的是属性初始化语法
    switchName=()=>{
       if(this.state.name==="Tom"){
          this.setState({name:"Jerry"});
        }else{
          this.setState({name:"Tom"});
        }
   } 
//render方法  渲染在UI上的内容
   render(){
      return(
        <div>
          <h1>hello,{this.state.name}</h1>
          <button onClick={this.switchName}>{this.state.name==="Tom"? "Jerry":"Tom"}</button>
        </div>
      );
   }

}   

ReactDOM.render(
  <GreetingInput/>,document.getElementById("root")
);
函数中this指针指向函数本身,因此,在class的构造函数中,需要将事件函数绑定到本类的实例

但箭头函数里的this指针,指向其拥有者,也就是class ,因此一个简易的方式是,在类中尽可能使用箭头函数定义函数

2、在回调函数中使用箭头函数

class GreetingInput extends React.Component{
//构造函数方法
    constructor(props){
        super(props);
        this.state={name:"Tom"};
        
    }
//自定义的switchName方法,用作事件处理
    switchName(){
       if(this.state.name==="Tom"){
          this.setState({name:"Jerry"});
        }else{
          this.setState({name:"Tom"});
        }
   } 
//render方法  渲染在UI上的内容   使用下边这个语法  有个问题就是每次switchName 渲染的时候都会创建一个不同的回调函数
   render(){
      return(
        <div>
          <h1>hello,{this.state.name}</h1>
          <button onClick={(e) => this.switchName(e)}>{this.state.name==="Tom"? "Jerry":"Tom"}</button>
        </div>
      );
   }

}   

ReactDOM.render(
  <GreetingInput/>,document.getElementById("root")
);

注意:当回调函数作为一个属性值传入低阶组件,上述这种方法可能会进行额外的重新渲染。

我们通常建议在构造函数中绑定或使用属性初始化器语法来避免这类性能问题。

原文地址:https://www.cnblogs.com/lihuijuan/p/8579142.html