前端入门React 三大属性之一 State

理解什么是 state ?

首先 我们用最通俗易懂的话来理解, 比如 每个人都有自己的状态 , 每个人的状态 都会影响 他的行为,

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

它的页面。

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

是数据, 我们将这些数据放在了页面上,那么是什么驱动着页面的改变呢? 是数据。 这时候我们只需要

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

  1. 首先我们用脚手架创建一个 react 项目
r1.jpg
  1. 启动 项目 进入 src / app.js 修改成如下文件
import React, { Component } from 'react'

export default class App extends Component {
  render() {
    console.log(this)
    return (
      
app组件
) } }
  1. 打开 控制台可以看见 如下
r2.jpg
  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 (
      
123
) } }

我们在 类 中 放了一个 构造器 constructor , 调用了 super ( 传递的props 不在本章见做详细说明 我们先写上 )

  1. 在构造器里 我们改变了实例对象里面的 state 这时候 我们启动项目 打开控制台
r3.jpg

可以看见 我们初始化好了 一个 状态 key : isHot value:true

  1. 读取状态 我们将 render 方法中的代码改为 如下:
    render() {
    console.log(this.state)
    return (
      

今天天气很{this.state.isHot ? '炎热' : '寒冷'}

) }

打开页面与控制台 我们查看一下

r4.jpg

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 (
      

今天天气很{this.state.isHot ? '炎热' : '寒冷'}

) } } function clickTitle() { console.log('标题被点击了'); }
  1. 我们打开控制台可以看见 我们还没有点击 , 控制台就已经打印了 。
r5.jpg

我们可以思考一下为什么 ?

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 (
      

今天天气很{this.state.isHot ? '炎热' : '寒冷'}

) } }

首先 我们只需要将 函数从实例的外面 放到实例的里面去

那么 clickTitle 这个方法放在哪儿了呢?

他放在了类的实例对象上,供实例使用

r6.jpg

所以 我们需要在

今天天气很{this.state.isHot ? '炎热' : '寒冷'}

这句话中 改成 this.clickTitle

启动项目 发现 标题依然是可以被点击的

接下来 我们将函数内的代码改为

clickTitle() {
    console.log(this.state.isHot);
}

这时 控制台就直接报错了

r7.jpg

我们再去打印 this 时会发现 this 是 undefined

我们可以知道 constructor 和 render 中的 this 都是指组件的实例对象 ,那么自己定义的clickTitle 里的this为什么是undefined呢

r8.jpg

首先我们要了解到 只有当 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)
  }

这个时候 我们去控制台 点击标题 查看一下

r9.jpg

this.clickTitle = this.clickTitle.bind(this) 这一段代码 本身是一个赋值语句 我们在实例对象本身加了一个方法 这个方法从那儿来的呢? 是从原型上来的

r10.jpg

React 中 setState 的使用

此处 我们接着上一个小节中的内容 继续 。

我们将函数体的内容改为 如下 :

clickTitle() {
    this.state.isHot = !this.state.isHot
  }

运行项目后 发现 点击标题依然不能改变标题的内容

我们打印 函数里的 this.state.isHot

r11.jpg

会发现 isHot的值确实在改变 但是为什么页面不更新呢

严重注意: state( 状态 ) 不可直接更改, this.state.isHot = !this.state.isHot 这一行是错误的写法

此处 我们需要借助 一个内置的 api 去更改state的值 setState() 。 我们在函数体内打印 this 可以找到

r12.jpg

在函数体内修改如下代码 :

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 (
      

今天天气很{this.state.isHot ? '炎热' : '寒冷'}

) } }

此处 我们将 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 (
      

今天天气很{this.state.isHot ? '炎热' : '寒冷'}

) } }

你可能感兴趣的:(前端入门React 三大属性之一 State)