浅析React类组件

React类组件(组件名首字母大写)
//创建类组件      组件名首字母大写
class  MyCom extends React.Component {render(){return (<div>类组件</div>)}
}
let com=<MyCom/>
ReactDOM.render(com,document.getElementById('app'));
react类组件的构造方法 constructor():
constructor(props){super(props);               this.state = {}
}
  • constructor必须用super()初始化this,可以绑定事件到this

  • 如果你在constructor中要使用this.props,就必须给super加参数,super(props)

    • constructor(){super();               this.state = {xxx:this.props.xxx//构造函数里面用到了props};
      }//这里如果在construct()和super()中不传入props参数,则会报错
      //因为这里使用super()是重写了父类的构造函数(父类的构造函数本来是super(props,context))
      
  • 无论有没有constructor(),重写的构造函数中参数有没有propsrender()中都可以使用this.props, 默认自带

  • 如果组件没有声明constructor,react会默认添加一个空的constructor

    • class News extends React.Component {render() {return (<div>new组件:{this.props.text}<p>{this.state.text}</p></div>)}
      }
      //如果在继承时,子类中如果没有声明constructor,js会自动生成添加constructor并且调用父类的构造函数
      //这里是父类的构造函数是super(props,context),并不是super()如果写super()则是不完全使用父类构造函数方法。
      
  • ES6采用的是先创建父类的实例this(故要先调用 super( )方法),完后再用子类的构造函数修改this

constructor( )-----super( )的基本含义

constructor( )——构造方法

这是ES6对类的默认方法,通过 new 命令生成对象实例时自动调用该方法。
并且,该方法是类中必须有的,如果没有显示定义,则会默认添加空的constructor( )方法。

super( ) ——继承

在class方法中,继承是使用 extends 关键字来实现的。
子类必须在 constructor( )调用 super( )方法,否则新建实例时会报错。
(如果子类没有显示定义构造方法,js则会默认加上构造方法并且里面用super自动调用父类的构造方法)
即:
class son extends father{constructor(){super()}
}
如果父类构造方法里面含参数,子类没有显示定义构造方法,js也会默认向子类构造方法中加上参数调用父类的构造方法,例如:
class son extends father{constructor(name,age){super(name,age)}
}报错的原因是:子类是没有自己的 this 对象的,它只能继承自父类的 this 对象,然后对其进行加工,而super( )就是将父类中的this对象继承给子类的。没有 super,子类就得不到 this 对象。
下面我们来举个很好的栗子,说明这一切:

下面是子类显示定义了构造方法,但是并没有向子类构造方法传入父类构造方法本应该传入的形参:

class father {constructor(name, age) {this.name = namethis.age = age}pick() {console.log(`年龄:${this.name}`, `年龄:${this.age}`)}
}
class son extends father {//显示定义了构造方法,但是没有向其中传入父类该有的形参constructor(name){//这里我们只传入第一个参数super(name)}pull() {console.log("jhhh ")}
}
Father = new father("baba", 40)
Father.pick()//年龄:baba 年龄:40
Son = new son("erzi", 20)
Son.pick()//年龄:erzi 年龄:undefined//可以看到此时子类虽然使用super继承使用了父类的构造方法,但是只会使用了父类的一个形参
class father {constructor(name, age) {this.name = namethis.age = age}pick() {console.log(`年龄:${this.name}`, `年龄:${this.age}`)}
}
class son extends father {//此时子类直接继承父类,并没有显示定义构造方法pull() {console.log("jhhh ")}
}
Father = new father("baba", 40)
Father.pick()//年龄:baba 年龄:40
Son = new son("erzi", 20)
Son.pick()//年龄:erzi 年龄:20//此时我们可以知道如果子类没有显示定义构造方法,
//则会默认补上父类的构造方法,而且构造方法的参数和父类都是一致的。

总结:通过这个我们知道如果在react类组件中写出构造函数而且需要在构造函数中使用props属性,必须补上第一个形参作为补位,才能使用得到props的值。

而这里需要注意的是:react类组件在render()函数中无论构造函数有没有传入props形参,render()函数都可以使用到this.props的值

注意:

类组件需要注意js内置事件回调函数的this指向问题。

1. 类组件有自己的状态
2. 继承React.Component-会有生命周期和this
3. 内部需要一个render函数(类组件会默认调用render方法,但不会默认添加,需要手动填写render函数,并return一个能渲染的值。)
4. 类组件的基本架构
5. constructor里边添加自己的属性和状态、方法a. 写了constructor就要写superb. 如果c里边没内容只有super,name可以不写
6. 添加状态this.state = {}; es7写法state = {}。非双向绑定
7. setState接收对象的情况、批量更新
8. setState接收函数的情况、state与penddingState
9. class里方法的写法a. 方法里边this的指向undefined的情况class Person {fn(){console.log(this);}}var person = new Person();var fn1 = person.fn;(这里是将值赋给fn1)fn1(); //undefined(fn1()当前的指向位置this指向undefined)b. bind改变this指向c. 箭头函数继承this指向d. 匿名函数传参
10. TodoList实战
11. 类组件注意:
注意绑定事件时,"on"后边事件名的首字母大写,如"change"要写成"Change"注意回调函数内部this的指向默认为undefined,要改变this指向
不能直接改变state的值、需要用函数setState来修改state的值

类组件内部没有render函数报错:

因为看到class组件会默认调用render方法
如果看到函数组件,会自动在函数内部添加一个render方法,把函数的return返回值放到render中运行。
所以类组件内部必须有render函数,并return返回一个可渲染的值。不会进行自动添加。

React中自定义事件this指向问题:

this是基于函数的执行环境(也就是上下文)绑定的,React组件生命周期函数中this的上下文就是组件实例。(而js的变量是通过词法作用域来绑定的)

  • 可以看关于this的一篇文章总结的很到位。

    • 1.函数在调用时,JavaScript会默认给this绑定一个值;
    • 2.this的绑定和定义的位置(编写的位置)没有关系;
    • 3.this的绑定和调用方式以及调用的位置有关系;
    • 4.this是在运行时被绑定的;

你必须谨慎对待 JSX回调函数中的this,类的自定义方法默认是不会绑定 this 的。首先调用 constructor()函数, this.statethis上下文就是该实例对象;同理,render() 函数中this也是该实例。

在浏览器中回调函数中的this默认是指向window,因为本质上是在函数内callback,并没有.前的对象调用,在**nodejs中的回调函数中的this默认是undefined**。(回调函数可以参看我之前的总结)

class Bar extends React.Component {constructor (){super();this.state = {value: 'react'}}changeValue (){console.log(this)  // undefined}render (){console.log(this) // 该组件实例return (<div><p>{this.state.value}</p><button onClick={this.changeValue}>click me !</button></div>)}
}

当我们直接绑定this.changeValue调用时,会发现他的thisundefined;你应该为和这个方法绑定this

解决方式:

①:使用 bind() 函数改变this的上下文(这里只能用bind,不能用call和apply,因为call和apply会立即执行,而bind不会)

call,apply,bind的用法以及区别

这里还是举个栗子来看一下区别:

 var obj = {message: 'My name is: '}function getName(firstName, lastName) {console.log(this.message + firstName + ' ' + lastName)}getName.bind(obj, ['Dot', 'Dolby'])//不会执行打印函数,而是返回一个改变了执行上下文this指向之后的函数getName.bind(obj, ['Dot', 'Dolby'])()// My name is: Dot DolbygetName.apply(obj, ['Dot', 'Dolby'])// My name is: Dot DolbygetName.call(obj, 'Dot', 'Dolby')// My name is: Dot Dolby

在这里就可以使用bind来改变回调函数上下文this的指向,并不需要让它马上执行

class Bar extends React.Component {constructor (){super();this.state = {value:'react'}}changeValue (e){console.log(e) // 默认eventthis.setState({value:`react ${parseInt(Math.random()*100)}`})}render (){return (<div><p>{this.state.value}</p><button onClick={this.changeValue.bind(this)}>click me !</button></div>)}
}

也可以在constructor()中:this.changeValue = this.changeValue.bind(this)

②:es6箭头函数
利用箭头函数将函数的this绑定到其定义时所在的上下文

<div><p>{this.state.value}</p><button onClick={(event) => this.changeValue(event)}>click me !</button>
</div>

或者

changeValue = (e) => {console.log(e) // 默认eventthis.setState({value:`react ${parseInt(Math.random()*100)}`})
}

React类组件里面的各种问题浅析相关推荐

  1. react hooks使用_如何使用Hooks将React类组件转换为功能组件

    react hooks使用 by Balaganesh Damodaran 通过Balaganesh Damodaran 如何使用Hooks将React类组件转换为功能组件 (How to conve ...

  2. [react] 类组件和函数式组件有什么区别?

    [react] 类组件和函数式组件有什么区别? 函数式组件没有state和一系列的钩子函数,只接收一个props 个人简介 我是歌谣,欢迎和大家一起交流前后端知识.放弃很容易, 但坚持一定很酷.欢迎大 ...

  3. 正则改造VS Code里React类组件的自定义snippet

    我目前都习惯用 JS JSX Snippets 这个 VS Code 插件来快速编写 React 组件,然后发现快速生成类组件的 rcc 其中的类名可以跟着当前文件名自动变化,于是就研究了一下. 最后 ...

  4. React 类组件和函数组件

    React 类组件和函数组件 目录 1.类组件和函数组件 2.如何使用 props 和 state 3.如何绑定事件 4.复习 this+ 两个面试题 组件component 一.概念 Element ...

  5. React类组件的两种写法

    react中类组件的两种写法: 要点:•类组件必须要继承React.Component •类组件中的render()方法,返回值是一个jsx // 方式一: import React from 're ...

  6. react类组件中父组件调用子组件函数

    1.自定义事件 子组件在 componentDidMount 生命周期里调用父组件的方法将 this 传给父组件 Son import React, { Component } from 'react ...

  7. react中类组件this的指向问题

    1.铺垫知识 a.普通函数的this指向 若是一个普通函数直接被调用,那this默认是指向全局的,若是非严格模式下,则是指向window的 function display(){console.log ...

  8. 函数式组件与类组件区别-心智模型

    与React类组件相比,React函数式组件究竟有何不同? 区别:心智模型不同,函数式组件捕获了渲染所用的值. 函数式组件与类组件有何不同? - Overreacted他们是完全不同的宝可梦哦.htt ...

  9. 这就是为什么我们需要在React的类组件中绑定事件处理程序

    by Saurabh Misra 索拉·米斯拉(Saurabh Misra) 这就是为什么我们需要在React的类组件中绑定事件处理程序 (This is why we need to bind ev ...

最新文章

  1. Eclipse Jetty 9.4.15 发布,建议使用 JDK 12
  2. pytorch dropout用法
  3. docker部署项目 dockerfile 实战 SpringBoot、flask
  4. 数据结构与算法-二叉查找树(java描述)
  5. 用rz,sz命令在xshell传输文件
  6. Android源码下 进行cts测试 和 cts的注意事项。
  7. Maven 项目关于 plexus-utils:jar的错误解决
  8. 克罗谈投资策略01_期货交易中的墨菲法则
  9. nyoj244 16进制的简单运算
  10. 第四次作业(胡明浩)
  11. DHCP中继原理与配置
  12. MySQL学习日志(二)
  13. 【POJ 2342】Anniversary party(入门树形dp)
  14. form空白及iframe空白处理
  15. 解决IDEA中maven搭建web项目,在maven中有依赖但是在部署包中生成不出依赖
  16. ASP.NET FileUpload用法
  17. python编写水仙花数
  18. 新版掌上阅读小说源码+支持公众号/分站/封装APP
  19. FL Studio 20.9水果编曲软件中文汉化补丁包
  20. java里VO是什么?

热门文章

  1. android 华为 多语言,原来华为手机自带翻译神器!这3个方法,一键实现多国语言翻译...
  2. excel中if多条件判断语句
  3. java贪吃蛇游戏代码下载_java实现贪吃蛇游戏代码(附完整源码)
  4. 名创优品怎么把创意做成生意?
  5. 战地2042 战地 6 建议 介入 流程
  6. 微信小程序 天气预测
  7. html5video播放不了怎么解决
  8. MySQL-SQL优化10大最经典案例详解
  9. javascript中双感叹号(!!)作用
  10. 44、电子邮件之一(应用层)