上一节课我们学习了关于state的一些概念性的东西,那么这节课我们开始正式地学习如何来使用state

回顾

当然在学习如何使用state之前,我们来对上节课的内容来做一个简单的回顾。

  • 组件有简单组件和复杂组件之分
  • 简单组件没有状态
  • 复杂组件有状态
  • 状态里面存储页面所需要的数据,数据更新则驱动页面展示
  • 状态在类组件实例对象上
  • 我们所说的组件的三大属性,实际上是组件实例的三大属性

以上便是我们上节课所学习的一些关于state的一些知识要点。

初始化state

通过上节课的学习,我们知道了state中存储的是数据,并且是用来驱动页面的。那么我们究竟要怎么样来使用state呢?我们通过一个案例来探讨一下。

比如我们现在有要做一个页面,页面上显示一句话: 今天天气很炎热,但是当我点击这句话的时候要求把炎热变成凉爽。再次点击的时候再重新把凉爽变成炎热

那么这个需求应该怎么写呢?

我们刚开始不要想那么多,先一步步来,先让页面上能够显示一句话:

1.创建组件,既然我要用组件示例的三大属性之一,那么我不用说肯定得用类组件

class Weather extends React.Component {
  render() {
    return (
      <h2>今天天气很炎热</h2>
    );
  }
};

ReactDOM.render(<Weather />, document.getElementById("test"));

我直接这样是不是就可以直接在页面上展示一句话叫今天天气很炎热

但是我们的需求是要求炎热这个次发生变化,而这两个字也只有两种变法:凉爽炎热。那么对于这种情况我们是不是可以定义一个标识用bool类型来做?因为我这个词只有两种状态,不是炎热就是凉爽,那么我们可以定义一个标识叫isHot如果isHot: true那我们就展示炎热,如果isHot: false那么我们就展示凉爽

但是我们应该怎么处理呢?现在我们有设计思路了,也知道该用state但是怎么用?

class Weather extends React.Component {
  render() {      
    console.log(this);
    return (
      <h2>今天天气很炎热</h2>
    );
  }
};

我们先来看一下这个组件的实例对象

image-20211214162133040

我们看见这个实例对象里面有我们的state,但是state里面却并没有我们想要的isHot这个属性。那我们就应该想办法怎么样把isHot这个属性传入到state里面去呢。

上节课中我们也介绍了,state属性在组件实例对象上,那么我们想要把isHot传到state里面,那就是说要变更实例对象的属性,那么就得借助构造器方法了。所以说,我们需要在我们的组件类里面写构造器方法。

class Weather extends React.Component {
  constructor(???) {

  }

  render() {
    console.log(this);
    return (
      <h2>今天天气很炎热</h2>
    );
  }
}

那么问题来了,这个构造器能接收到什么呢?在我们之前学习class相关的知识的时候是不是都有了解过,构造器方法能接到什么,取决于实例化对象时候传了些什么。

但是组件类实例化的时候我们并没有自己来实例化啊。或许有人要说那我这个构造器方法该怎么写嘛,我都不知道实例化的时候回传入什么东西。

没有关系,我也不知道怎么写。但是没有关系。我们来看一下官方文档中给的示例:

image-20211214170449418

官方给的示例中写了构造器方法,而且接受到了props,而且调用super方法的时候还讲props传了进去,这个词大家可能也挺熟悉的,组件三大核心熟悉之一嘛,但是这里就只是个参数。

既然看了官方文档给的示例这么写,那么我们就学着来。

class Weather extends React.Component {
  constructor(props) {
    super(props);
    this.state = true;
  }

  render() {
    console.log(this);
    return (
      <h2>今天天气很炎热</h2>
    );
  }
}

这样我们设置了state那么这么写对吗?其实在语法上是没有问题的,是对的。但是不满足我们的需求,因为这样写不合理。如果我需要的state里面要有两个不同类型的标识的话怎么办呢?所以说我们不能这么写。

其实react官方要求我们要把state写成一个对象。所以说这一段代码应该这么来写

class Weather extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isHot: true };
  }

  render() {
    console.log(this);
    return (
      <h2>今天天气很炎热</h2>
    );
  }
}

我们来看一下现在是不是已经可以改变state

image-20211214173256911

我们从图中可以看出state已经变成了我们指定的对象。但是我们这么写了,我们这么用起来呢?我们之前也说了天气炎热还是凉爽取决于isHot。现在我们要做的就是从state中把isHot读取出来然后做判断了。

那么怎么读?我们来分析一下:stateWeather组件的实例对象上,而render方法中的this指向的就是Weather组件的实例对象。那么是不是我们通过this.state就可以读取到state了呢?那我们试试呗?没病走两步:

class Weather extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isHot: true };
  }

  render() {
    console.log(this);
    return (
      <h2>今天天气很{this.state.isHot ? "炎热" : "凉爽"}</h2>
    );
  }
}

那么我们来看一下效果,然后把isHot改成false再看一下

image-20211214174201983image-20211214174303519

这下一看那我们确实已经成功地读取到了state并且用来驱动了页面。所以state的初始化和读取都已经完成了。

但是我们目前还是不符合我们的需求啊,我们要点击文章来回切换的啊。那我们是不是就需要通过某些方法来是的我们这个state来进行一个动态的修改。而state一旦发生改变就会驱动页面发生改变,然后就可以满足页面上展示的内容动态改变。

但是我们这里所说的某些方法又是指什么呢?这节课我们先不讨论这个问题。下节课我们再展开讨论怎么去动态改变state

总结

  • 如果通过state驱动页面需要借助构造器方法
  • 构造器方法的参数官方规定的是props
  • 构造器方法要将props参数传给super
  • state要传一个对象
  • 通过this来调用state

Copyright statement:The articles of this site are all original if there is no special explanation, indicate the source please when you reprint.

Link of this article:https://work.lynchow.com/article/init_state/