React面向组件编程 函数式组件 & 类式组件的核心属性之一State

函数式组件

准备好容器

<div id='test'></div>
<script type = "tsext/babel">
//1. 创建函数式组件
function MyComponent() {
	console.log(this)
	//这个this是undefined,由于jsx代码经过babel翻译,
	//开启了严格模式,严格模式下禁止自定义的函数指向window
	//所以这个this指向了undefined
	return <h2>我式用函数式定义的组件,适用于【简单组件】的定义</h2>
}
//2. 渲染组件到页面,记得jsx标签必须闭合
ReactDOM.render(<MyComponent/>,document.getElementById('test'))
</script>

执行了React DOM……之后发生了什么?

  1. React解析组件标签,找到了MyComponet组件
  2. 发现组件时使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DOM,随后呈现在页面中

类的基本知识

//创建一个Person类
class Person {
	//构造器方法
	constructor(name,age){
		this.name = name
		this.age = age
	}
	//一般方法,除了构造器以外,自己写的都叫一般方法
	speak(){
	//speak方法放在了类的原型对象上,提供实例使用
	//通过person实例调用speak时,speak中的this就是person实例
		console.log("我叫${this.name}我的年龄是${this.age}")
		//${}es6模板字符串
	}
}
const p1 = new Person('tom',18);
const p2 = new Person('jerry',18);

console.log(p1);
console.log(p2);
p1.speak();
p2.speak();

类的继承


```javascript
//创建一个Student类,继承person类
class Student extends Person {
	//构造器方法
	constructor(name,age,grade){
	//super必须放在最前面
		super(name,age)
		this.grade = grade
	}
	speak() {
	//重写父类继承过来的speak方法
		console.log("我叫${this.name}我的年龄是${this.age}我读${this.grade}年级")
	}
	study() {
	//study放在类的原型对象,供实例使用
	//通过Student对象调用时,this指向实例对象
	console.log("我很努力学习")
	}
}
const s1 = new Student("小明"17);
console.log(s1);
s1.speak();

总结

  1. 类的构造器不是必须写的,要对实例进行一些初始化的操作,如添加指定属性时才写
  2. 如果A类继承了B类,A类中写了构造器,那么A类构造器中的super方法是必须要调用的,且必须放在最前面
  3. 类中所定义的方法,都是放在了类的原型对象上,供实例使用

类式组件

<script type="text/babel"> 
	//1. 创建类式组件,类必须继承React内置的类React.Component
	class MyComponent extends React.Component{
		//2. 必须写render,并且render必须有返回值
		render() {
		//render放在MyComponent的原型对象上,供实例使用
		//render中的this指向MyComponent的实例对象(MyComponent组件实例对象)
		console.log(this);
			return <h2>我式用函数式定义的组件,适用于【复杂组件】的定义</h2>
		}
	}
	//渲染组件到页面
	ReactDOM.render(<MyComponent />,document.getElementById('test'));
</script>

执行了React DOM……之后发生了什么?

  1. React解析组件标签,找到了MyComponet组件
  2. 发现组件时使用类定义的,随后new出来该类的实例,并通过该实例调用到原型上的render方法
  3. 将render返回的虚拟DOM转为真实DOM,随后呈现在页面中

复杂组件 简单组件

如果组件有状态,就是复杂组件
没有状态则是,简单组件

  • 组件状态驱动页面

组件实例的三大核心属性

旧版本中函数式组件没有这三个属性

state

<script type="text/babel">
      //1. 创建组件
      class Weather extends React.Component {
        constructor(props) {
          super(props);
          this.state = { isHot: true };
        }

        render() {
          const { isHot } = this.state;//解构赋值
          return <h1>今天天气很{isHot ? "炎热" : "凉爽"}</h1>;
        }
      }
      ReactDOM.render(<Weather />, document.getElementById("test"));
    </script>

React事件的绑定

类中方法中的this

类中所有定义的方法,在局部都开启了严格模式

 <script type="text/babel">
      //1. 创建组件
      class Weather extends React.Component {
        constructor(props) {
          super(props);
          this.state = { isHot: true };
          //解决changeWeather中this指向问题
          this.changeWeather = this.changeWeather.bind(this);
        }

        render() {
          const { isHot } = this.state;
          return (
            <h1 id="title" onClick={this.changeWeather}>
              今天天气很{isHot ? "炎热" : "凉爽"}
            </h1>
          );
        }
        changeWeather() {
          //changeWeather放在了weather的原型对象上,供实例使用
          //【通过weather的实例】调用changeWeather时,this就是weather实例
          //由于changeWeather是作为onclick的回调,所以不是通过实例调用的,是直接调用
          //类中的方法默认开启了局部的严格模式,所以changeweather中的this是undefined
          alert("Hello world!");
          this.state.isHot = false;
          console.log(this);
        }
      }
      ReactDOM.render(<Weather />,document.getElementById("test"));
 </script>

setState

React状态中的数据不能够直接更改,要借助一个内置的API修改——setState

  • setState更新是一种合并,不是替换。
  • 构造函数只调用1次,render调用1+n次
  • changeWeather点几次调用几次
<script type="text/babel">
      //1. 创建组件
      class Weather extends React.Component {
        constructor(props) {
          //构造器调用一次
          super(props);
          this.state = { isHot: true };
          //解决changeWeather中this指向问题
          this.changeWeather = this.changeWeather.bind(this);
        }

        //render调用1+n次
        render() {
          const { isHot } = this.state;
          return (
            <h1 id="title" onClick={this.changeWeather}>
              今天天气很{isHot ? "炎热" : "凉爽"}
            </h1>
          );
        }
        //change weather点几次调几次
        changeWeather() {
          //changeWeather放在了weather的原型对象上,供实例使用
          //【通过weather的实例】调用changeWeather时,this就是weather实例
          //由于changeWeather是作为onclick的回调,所以不是通过实例调用的,是直接调用
          //类中的方法默认开启了局部的严格模式,所以changeweather中的this是undefined

          //严重注意!!状态不可以直接更改,下面这行就是直接更改
          //   this.state.isHot = !isHot;
          //严重注意!!要借助一个内置的API更改,setState,且更新是一种合并,不是替换
          const isHot = this.state.isHot; //回去原来的isHot值
          this.setState({ isHot: !isHot });

          console.log(this);
        }
      }
      ReactDOM.render(<Weather />, document.getElementById("test"));

    </script>

state简写

  • 自定义的方法要写成:赋值语句 + 箭头函数
  • 解决this的问题
  • state当作属性直接写出来
<script type="text/babel">
      class Weather extends React.Component {
        //初始化状态
        state = { isHot: true };
        render() {
          const { isHot } = this.state;
          return (
            <h1 id="title" onClick={this.changeWeather}>
              今天天气很{isHot ? "炎热" : "凉爽"}
            </h1>
          );
        }
        //自定义方法——要用赋值语句+箭头函数
        changeWeather = () => {
          const isHot = this.state.isHot; 
          this.setState({ isHot: !isHot });
        }
      }
      ReactDOM.render(<Weather />, document.getElementById("test"));
    </script>

总结

  1. state是组件对象最重要的属性,它的值是一个对象
  2. 组件被成为”状态机“,通过更新组件的state来更新对应页面显示(重新渲染组件)
  3. 强烈注意!!
    3.1 组件中render方法中的this为组件实例对象
    3.2 组件中自定义的方法中this为undefiend
    3.2 a. 强制绑定this:通过函数对象的bind()
    3.2 b. 赋值语句 + 箭头函数
    3.3 状态数据不能直接修改或更新,必须通过setState更新
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值