共计 4286 个字符,预计需要花费 11 分钟才能阅读完成。
了解什么是 state ?
首先 咱们用最通俗易懂的话来了解,比方 每个人都有本人的状态,每个人的状态 都会影响 他的行为,
那么,咱们将这句话放到 react 中去了解,把人看作是 组件,组件也有本人的状态,组件的状态会影响
它的页面。
咱们在旅行各大网页时,会发现 网页上有一些数据,如个人信息 账号 以及一些新闻列表等等。这些都
是数据,咱们将这些数据放在了页面上,那么是什么驱动着页面的扭转呢?是数据。这时候咱们只须要
将数据 放入状态 (state) 中,咱们去更改状态 页面也会随之变动。
- 首先咱们用脚手架创立一个 react 我的项目
- 启动 我的项目 进入 src / app.js 批改成如下文件
import React, {Component} from 'react'
export default class App extends Component {render() {console.log(this)
return (
<div>
app 组件
</div>
)
}
}
- 关上 控制台能够看见 如下
- 咱们在 render() 办法中 打印了 this 能够看见在这个组件的实例对象下面。曾经有一个 state 了(这就是 react 给你筹备好的状态)
当初咱们回到 第一个问题 了解什么是 state ?
1 . state 是组件对象最重要的属性,值是对象(外面能够蕴含多个 key : value 的 组合)尽管在初始化看到的是 null,在 react 之前的版本中 还是一个 {}
2 . 组件被称之为状态机,通过更新组件里的 state 来更新对应的页面显示(从新渲染组件)
须要留神的中央:因有函数时组件与类式组件 react 将状态放到了 实例对象里 函数时组件 连 this 都没有 哪儿来的 状态呢?在思考初学者未接触到 hooks
咱们 先从 类 组件来说。
初始化 state
- 首先 咱们新建一个组件 如下:
import React, {Component} from 'react'
export default class App extends Component {constructor(props) {super(props)
// 初始化状态
this.state = {isHot: true}
}
render() {console.log(this)
return (<div>123</div>)
}
}
咱们在 类 中 放了一个 结构器 constructor,调用了 super (传递的 props 不在本章见做具体阐明 咱们先写上)
- 在结构器里 咱们扭转了实例对象外面的 state 这时候 咱们启动我的项目 关上控制台
能够看见 咱们初始化好了 一个 状态 key : isHot value:true
- 读取状态 咱们将 render 办法中的代码改为 如下:
render() {console.log(this.state)
return (<h2> 今天天气很 {this.state.isHot ? '酷热' : '凛冽'}</h2>
)
}
关上页面与控制台 咱们查看一下
React 中的事件绑定
须要留神的是 原生 js 中的 onclick , onblur … 等等 在 React 中 全副改为 onClick onBlur 这种小驼峰的写法
- 接下来 咱们批改 代码如下
import React, {Component} from 'react'
export default class App extends Component {constructor(props) {super(props)
this.state = {isHot: true}
}
render() {
return (<h2 onClick={ clickTitle() }> 今天天气很 {this.state.isHot ? '酷热' : '凛冽'}</h2>
)
}
}
function clickTitle() {console.log('题目被点击了');
}
- 咱们关上控制台能够看见 咱们还没有点击,控制台就曾经打印了。
咱们能够思考一下为什么?
onClick = {clickTitle() } 同等于 onClick = {函数调用的返回值}
咱们将返回值 间接给到了 onClick 他就主动的去给你点了
咱们将 onClick = {clickTitle() } 前面的调用给去掉 改为 onClick = {clickTitle}
从新回到页面 咱们能够看到 曾经能够进行失常的点击操作了
类办法中的 this
此处 咱们接着上一个大节中的内容 持续。
我须要 点击题目的时候 让酷热变成凛冽 这个时候怎么去解决?咱们须要将代码批改成 如下:
import React, {Component} from 'react'
export default class App extends Component {constructor(props) {super(props)
this.state = {isHot: true}
}
clickTitle() {console.log('题目被点击了');
}
render() {
return (<h2 onClick={ this.clickTitle}> 今天天气很 {this.state.isHot ? '酷热' : '凛冽'}</h2>
)
}
}
首先 咱们只须要将 函数从实例的里面 放到实例的外面去
那么 clickTitle 这个办法放在哪儿了呢?
他放在了类的实例对象上,供实例应用
所以 咱们须要在
<h2 onClick={this.clickTitle}> 今天天气很 {this.state.isHot ? '酷热' : '凛冽'}</h2>
这句话中 改成 this.clickTitle
启动我的项目 发现 题目仍然是能够被点击的
接下来 咱们将函数内的代码改为
clickTitle() {console.log(this.state.isHot);
}
这时 控制台就间接报错了
咱们再去打印 this 时会发现 this 是 undefined
咱们能够晓得 constructor 和 render 中的 this 都是指组件的实例对象,那么本人定义的 clickTitle 里的 this 为什么是 undefined 呢
首先咱们要理解到 只有当 clickTitle 这个办法 是组件的实例对象去调用的时候 它外面的 this 才是 clickTitle 的实例对象
constructor 里的 this 肯定是以后实例的 实例对象 是一个固定的货色
留神:咱们须要晓得的是 clickTitle 在调用的时候 并不是 App 这个实例对象去调用他的
这时候 再思考一个问题 既然不是 这个实例去调用他的 那 this 为什么是 undefined 不是 window 呢 ?
留神:在类中 所定义的办法 它会主动的去在你所定义的办法外面 开启严格模式 开启严格模式后 this 就是 undefined 是 类 主动帮你开启的
解决类中 this 的指向问题
在 constructor 里 加一段代码 如下
constructor(props) {super(props)
this.state = {isHot: true}
// 解决 this 的指向问题
this.clickTitle = this.clickTitle.bind(this)
}
这个时候 咱们去控制台 点击题目 查看一下
this.clickTitle = this.clickTitle.bind(this) 这一段代码 自身是一个赋值语句 咱们在实例对象自身加了一个办法 这个办法从那儿来的呢?是从原型上来的
React 中 setState 的应用
此处 咱们接着上一个大节中的内容 持续。
咱们将函数体的内容改为 如下:
clickTitle() {this.state.isHot = !this.state.isHot}
运行我的项目后 发现 点击题目仍然不能扭转题目的内容
咱们打印 函数里的 this.state.isHot
会发现 isHot 的值的确在扭转 然而为什么页面不更新呢
重大留神:state(状态) 不可间接更改,this.state.isHot = !this.state.isHot 这一行是谬误的写法
此处 咱们须要借助 一个内置的 api 去更改 state 的值 setState()。咱们在函数体内打印 this 能够找到
在函数体内批改如下代码:
clickTitle() {this.setState({ isHot: !this.state.isHot})
}
这时 咱们点击 页面中的 题目 就能够进行切换了
留神:批改 state 的值 必须应用 setState 来批改,且 批改是一个合并的动作 并不是间接替换 setState 调用几次 render 这个办法就会调用几次 能够本人打印试试
State 的简写形式
将代码改成 如下:
import React, {Component} from 'react'
export default class App extends Component {// constructor(props) {// super(props)
// this.state = {//}
// this.clickTitle = this.clickTitle.bind(this)
// }
state = {isHot: true}
// clickTitle() {// this.setState({ isHot: !this.state.isHot})
// }
clickTitle = () => {this.setState({ isHot: !this.state.isHot})
}
render() {
return (<h2 onClick={this.clickTitle}> 今天天气很 {this.state.isHot ? '酷热' : '凛冽'}</h2>
)
}
}
此处 咱们将 state 从 constructor 间接拿进去
在类中,咱们间接写一个赋值的语句 相当于 咱们在 APP 这个实例对象上 新加了一个属性 属性的名字 是 state 它的值是 {isHot:true}
而后 在将 this.clickTitle = this.clickTitle.bind(this) 给正文掉
同样 咱们在实例对象上 新增了一个办法 为 clickTitle 值 是一个 箭头 函数 这样就解决掉了 this 的指向问题 防止在 constructor 频繁的 应用 bind 绑定 this
将这两行 正文掉了当前 咱们齐全能够将 constructor 这个结构器 给正文掉,因为咱们没有在外面写任何的内容
以下为残缺代码
import React, {Component} from 'react'
export default class App extends Component {
// 初始化状态
state = {isHot: true}
// 自定义办法 须要采纳 赋值语句的模式 + 箭头函数
clickTitle = () => {this.setState({ isHot: !this.state.isHot})
}
// 渲染
render() {
return (<h2 onClick={this.clickTitle}> 今天天气很 {this.state.isHot ? '酷热' : '凛冽'}</h2>
)
}
}