赞
踩
目录
state 指状态,而状态即是驱动页面进行渲染是数据。
在类式组件内,输出实例对象的this。可以看到state默认值为null
以天气是否炎热为例。我们理由 isHot 属性来判断,那么isHot就是状态之一。
在类内,构造器方法内,首先设置props ,关于props后续再聊。只用知道props的接受要使用super
然后设置state,使用this.state 来进行赋值,由于状态不止一种,所以赋值对象。在这里可以类比vue内的data
- // 要传入状态,参数,可能会使用到props,而props 必须使用super来调用
- constructor(props){
- super(props)
- // state则不需要使用super来设置调用,未设置式 state为null,可以设置成对象,因为state内可能不止一个数据
- this.state = {isHot:false}
- }
state存放在实例对象上。渲染组件时,是调用的render()方法,所以在render内,this指代组件实例,所以this.state 可以获取到state的值。
为了方便使用,选择解构赋值,将要使用的属性简化。
- render(){
- // 要理解,这里的this,是指渲染时,调用了render()的组件实例
- console.log(this);
- const {isHot} = this.state // 解构赋值
- return <h1>今天天气很{isHot?'炎热':'凉爽'}</h1>
- }
在 标签内的使用,类似与vue的插值语法,只是这里只使用一个花括号。在花括号内进行使用即可。
<h1>今天天气很 {isHot?'炎热':'凉爽'} </h1>
事件绑定使用最简单的方法,然后事件名被React重写了,变成小驼峰法。
onclick ==> onClick , onblur ==> onBlur
首先等式右侧不是字符串,而是花括号赋值{}。其次是写调用的函数名称,用this.函数名
- // 绑定事件
- // 1、事件名被重写,小驼峰法
- // 2、事件名等式右侧不是字符串"demo()",而是赋值语句,用花括号包裹。
- // 同时调用的函数只写函数名,不能加小括号,否则就理解成调用函数并将函数的返回值赋予等式右边,最终是{demo}
- return <h1 onClick={this.changeWeather}>今天天气很{isHot?'炎热':'凉爽'}</h1>
因为是组件化开发,所以写在类似组件内部。不用加function
在组件内部,组件实例上调用,所以使用 this.方法名
如果是作为点击事件的回调,因为 写了 onClick={this.changeWeather}> ,类中方法是局部严格模式,所以this就变成了undefined。
- // 1、由于是组件化开发,所以是把关于组件的全部东西都放在组件内。那么js调用的函数,比如点击,鼠标等就应该写在类式组件内部。
- // 2.关于调用。因为是写在组件内部,那么changeWeather这个方法在哪里?————在Weather的实例对象上
- // 那么render内的标签,要使用就得 使用 this.方法名。 onClick={this.changeWeather}>
-
- changeWeather(){
- // 3、在弄懂了上面的是1和2之后,接下来要弄懂这个方法里的this
- // 3.1 如果是组件实例调用,this就是组件本身
- // 3.2 但是这里是通过点击事件,将changeWeather方法作为回调来使用,也就是把方法赋值给了 h1 里面的 onClick。再加上,类中的方法默认开启了局部的严格模式。所以 点击h1时,this就是undefined。也就找不到 this下的state
- console.log("changeWeather",this);
- }
在构造器内利用bind方法,将this复制给新的函数,新函数在挂到实例上。
- constructor(props){
- ......
- // 4、解决类中方法的this指向问题
- this.changeWeather = this.changeWeather.bind(this)
- // 原理是利用了bind方法,将参数对象传入,并根据前面的函数生成了新的函数。
- /*
- 过程:bind先将this传入到了 changeWeather里,因为 changeWeather 不在实例自身上,而在原型上,所以找到原型上的 changeWeather。
- 然后把this传入,接着生成了新的函数,在这个函数内,this就指向了组件实例对象。最后再把这个新函数赋值给实例。
- 至此有两个 changeWeather,一个在实例身上,一个在实例的原型上。
- 最后,我们在调用的时候,就是调用实例身上的,没有再去原型上找。
- */
- }
经过上面的学习,解决了this指向问题。就可以获取state的属性,修改state了。
但是必须使用setState()方法,否则React无法检测到state状态的变化,从而重新渲染界面
- changeWeather(){
- // 读取 isHot ,然后修改
- // 注意:!!! 修改state只能使用setState方法,然后传入对象,来进行修改。因为state不止一个状态
- const isHot = this.state.isHot
- // 使用 setState 修改。传入对象。 更新状态是合并,不是替换。其他状态依旧存在。
- this.setState({isHot:!isHot})
-
- // 下面这种写法是错误的,属于直接修改
- // this.state.isHot = !isHot ❌
- }
利用了在类中可以写赋值语句的方法,来实现简化。
在类里直接写 state = {}
- class Weather extends React.Component {
- // 由于在类里面不能定义,但是可以直接赋值,所以我们可以直接写赋值语句,来进行简化。
- state = {isHot:false,wind:"微风"}
- }
使用赋值语句 + 箭头函数。即简化了写法,也利用箭头函数查找this的特性解决了原先的this指向问题
- class Weather extends React.Component {
- // 简写自定义函数的方法: 赋值语句 + 箭头函数
- // 箭头函数的特点,当在函数体内找不到this的时候,会在函数外查找this,而此时的this就是组件实例自身。也就不存在this的指向问题
- changeWeather = ()=>{
- // 读取 isHot
- const isHot = this.state.isHot
- // setState 修改
- this.setState({isHot:!isHot})
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。