了解什么是 state ?

首先 咱们用最通俗易懂的话来了解, 比方 每个人都有本人的状态 , 每个人的状态 都会影响 他的行为,

那么, 咱们将这句话放到 react 中去了解,把人看作是 组件,组件也有本人的状态,组件的状态会影响

它的页面。

咱们在旅行各大网页时,会发现 网页上有一些数据,如个人信息 账号 以及一些新闻列表等等。 这些都

是数据, 咱们将这些数据放在了页面上,那么是什么驱动着页面的扭转呢? 是数据。 这时候咱们只须要

将数据 放入状态 ( state ) 中 ,咱们去更改状态 页面也会随之变动。

  1. 首先咱们用脚手架创立一个 react 我的项目

  1. 启动 我的项目 进入 src / app.js 批改成如下文件
import React, { Component } from 'react'export default class App extends Component {  render() {    console.log(this)    return (      <div>        app组件      </div>    )  }}
  1. 关上 控制台能够看见 如下

  1. 咱们在 render() 办法中 打印了 this 能够看见在这个组件的实例对象下面。曾经有一个 state 了 ( 这就是react 给你筹备好的状态 )

当初咱们回到 第一个问题 了解什么是 state ?

1 . state 是组件对象最重要的属性 ,值是对象 ( 外面能够蕴含多个 key : value 的 组合 ) 尽管在初始化看到的是null , 在react之前的版本中 还是一个 { }

2 . 组件被称之为状态机 , 通过更新组件里的 state 来更新对应的页面显示 ( 从新渲染组件 )

须要留神的中央 : 因有函数时组件与类式组件 react 将状态放到了 实例对象里 函数时组件 连this都没有 哪儿来的 状态呢? 在思考初学者未接触到 hooks

咱们 先从 类 组件来说。

初始化 state

  1. 首先 咱们新建一个组件 如下 :
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 不在本章见做具体阐明 咱们先写上 )

  1. 在结构器里 咱们扭转了实例对象外面的 state 这时候 咱们启动我的项目 关上控制台

能够看见 咱们初始化好了 一个 状态 key : isHot value:true

  1. 读取状态 咱们将 render 办法中的代码改为 如下:
    render() {    console.log(this.state)    return (      <h2>今天天气很{this.state.isHot ? '酷热' : '凛冽'}</h2>    )  }

关上页面与控制台 咱们查看一下

React 中的事件绑定

须要留神的是 原生js 中的 onclick , onblur ... 等等 在 React 中 全副改为 onClick onBlur 这种小驼峰的写法
  1. 接下来 咱们批改 代码如下
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('题目被点击了');}
  1. 咱们关上控制台能够看见 咱们还没有点击 , 控制台就曾经打印了 。

咱们能够思考一下为什么 ?

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>    )  }}