0202state详解-组件-React

news2025/1/12 10:55:20

文章目录

    • 1 state简介
    • 2 初始化state
    • 3 React中事件绑定
    • 4 类方法中this指向问题
    • 5 解决React类组件方法this指向
    • 5 setState
      • 5.1 更新state状态数据方式
      • 5.2 更新state整体替换还是合并相同项?
      • 5.3 关于构造器、render方法调用次数
    • 6 state简写
    • 7 问题解答
    • 后记

1 state简介

React中没有state(状态)的组件称为简单组件;有state称为复杂组件。

  • 理解
    • state是组件对象最重要的属性之一,值是对象(1个或者多个key-value组合)
    • 组件被称为状态机,通过更新组件的state来更新对应页面显示(重新渲染组件)

下面我们来一步一步认识state,并最后给出日常开发中使用state的形式。

2 初始化state

下面展示一个小案例,通过点击文本,来切换今天的天气,如下图2-1所示:

在这里插入图片描述

第一步先把文本通过React组件显示在页面上,代码2-1如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>组件对象三大属性之一state</title>
</head>
<body>
  <div id="test"></div>
  <script type="text/javascript" src="../js/react.development.js"></script>
  <script type="text/javascript" src="../js/react-dom.development.js"></script>
  <script type="text/javascript" src="../js/babel.min.js"></script>

  <script type="text/babel">

    // 1.类式组件
  class Weather extends React.Component {
    constructor(props) {
      super(props)
      // 初始化状态
      this.state = {isHot: false}
    }
    render() {
     // 读取状态
      console.log(this);
      return <h2>今天天气很{this.state.isHot? '炎热': '凉爽'}</h2>
    }
   }
    // 2.渲染虚拟DOM到页面
    ReactDOM.render(<Weather/>, document.getElementById('test'))
  </script>
</body>
</html>

state初始化及访问步骤:

  1. 在构造函数中this.state=值(对象)
  2. 在render方法中{}内this.state.key访问key对应的值

注:

  1. state是Weather实例中的属性,要想初始化需要借助构造器。
  2. render中的this就是当前组件的实例对象

问题:

  1. Weather实例不是由我们new,而是React创建的,React在创建时,构造函数传递了那些参数呢?
  2. 构造器中的super能不能省略呢?

借助开发者工具查看下组件实例,如下图2-1所示:

在这里插入图片描述

3 React中事件绑定

在上面呢,我们完成了state的初始化和读取,实现了文本的展示,那么如果通过鼠标点击来完成切换呢?

参考js很容易想到,要通过绑定鼠标点击事件来完成。那么在Reac中如何绑定事件呢?

第一步在类中定义鼠标点击处理函数:

    changeWeather() {
      console.log(this);
      this.state.isHot = !this.state.isHot
    }

第二步在render函数返回标签上绑定点击事件:

    render() {
      // 读取状态
      console.log(this);
      return <h2 onClick={this.changeWeather}>今天天气很{this.state.isHot ? '炎热' : '凉爽'}</h2>
    }

注:

  1. onClick遵循小驼峰命名规则
  2. this.changeWeather后不加()

鼠标点击查看console输出:

undefined
Inline Babel script:25 Uncaught TypeError: Cannot read properties of undefined (reading 'state')

为啥呢?下面讲解

4 类方法中this指向问题

示例代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>3_类方法中this的指向</title>
</head>
<body>
  <script type="text/javascript">
    class Person {
      constructor(name, age) {
        this.name = name
        this.age = age
      }
      
      speak() {
        // speak方法放在Person类原型对象上,供实例使用
        // 通过Person实例调用本方法,方法中的this指向Person实例
        // 类中普通方法默认开启严格模式
        console.log(this);
      }
    }

    const p1 = new Person('zhangsan', 25)
    // 通过实例调用类方法
    p1.speak()
    // 直接调用方法,因为默认开启了严格模式,this为undefied
    const f1 = p1.speak
    f1()

    function demo1() {
      console.log(this);
    }

    function demo2() {
      'use strict'
      console.log(this);
    }

    demo1()
    demo2()
  </script>
</body>
</html>

输出:

Person
undefined
Window
undefined

5 解决React类组件方法this指向

解答下上面为什么点击,调用changeWeather(),输出是undefied问题?

onClick={this.changeWeather},这里为鼠标点击之前,通过this实例原型链找到changeWeather方法,交给onClick用于回调。当点击的时候属于直接调用changeWeather()方法,而不是通过Weather的实例对象。

又因为类中普通方法默认开启严格模式,且经过babel翻译,所以是undefined不是windows也不是Weather实例

解决方案一:既然此处是非实例调用,导致this执行改变,那么我们通过bind方法改变this指向为Weather实例并重新放置在Weather实例上。

代码调整如下:

  <script type="text/babel">

    // 1.类式组件
  class Weather extends React.Component {
    constructor(props) {
      super(props)
      // 初始化状态
      this.state = {isHot: false}
      this.changeWeather = this.changeWeather.bind(this)
    }
    render() {
      // 读取状态
      console.log(this);
      return <h2 onClick={this.changeWeather}>今天天气很{this.state.isHot ? '炎热' : '凉爽'}</h2>
    }
    changeWeather() {
      // changeWeather放在了哪里?Weather的原型对象上,供实例使用
      // 由于changeWeather上作为onClick的回调,所以不是通过实例调用的,上直接调用
      // 类中的方法默认开启了严格模式,所以changeWeather中的this为underfided
      // console.log(this);
      let isHot = this.state.isHot
      this.state.isHot = !isHot
      console.log(this.state.isHot);
    }
   }
    // 2.渲染虚拟DOM到页面
    ReactDOM.render(<Weather/>, document.getElementById('test'))

解决方案二:我们把一个匿名函数交给onClick回调,匿名函数内部执行this.changeWeather()方法,此时this就是Weather实例。

调整代码如下:

  class Weather extends React.Component {
    constructor(props) {
      super(props)
      // 初始化状态
      this.state = {isHot: false}
    }
    render() {
      // 读取状态
      console.log(this);
      // 匿名函数
      return <h2 onClick={() => this.changeWeather()}>今天天气很{this.state.isHot ? '炎热' : '凉爽'}</h2>
    }
    changeWeather() {
      // changeWeather放在了哪里?Weather的原型对象上,供实例使用
      // 由于changeWeather上作为onClick的回调,所以不是通过实例调用的,上直接调用
      // 类中的方法默认开启了严格模式,所以changeWeather中的this为underfided
      // console.log(this);
      let isHot = this.state.isHot
      this.state.isHot = !isHot
      console.log(this.state.isHot);
    }
   }

其他代码同上

不管是第一种bind改变this执行,还是事件监听回调绑定匿名函数都可以把上面的问题解决,但是鼠标点击,页面并没有和预想的一种,点击切换天气,这又是啥问题呢?明明this.state.isHot的值在控制台打印是改变了的。下面5setState部分给出解答。

5 setState

5.1 更新state状态数据方式

react中state中状态数据,不可直接更改,需要借助内置的API(setState)更改。

继续调整changeWeather()方法中更改数据的方式,如下:

    changeWeather() {
      // 状态需要通过setState修改, 且更新是一种合并,不是替换
      this.setState({isHot: !this.state.isHot})
    }

该setSate()放置在React.Component原型对象上,可以直接通过this调用。

5.2 更新state整体替换还是合并相同项?

那么this.state的值是一个对象,我们单独更新其中一个key-value,结果是整体替换还是合并原有的this.state值呢?

测试,在this.state初始化中在加一个key-value,如下

    constructor(props) {
      super(props)
      // 初始化状态
      this.state = {isHot: false, wind: '微风'}
    }

如下图所示:在这里插入图片描述

React的state中的状态数据更新是合并更新,相同key替换对应的值,不同保持原样。

现象:

  • 开发者工具中value值更新并不实时,有一定延迟,不知道啥原因。

5.3 关于构造器、render方法调用次数

  • 构造器:组件实例化时才执行,即页面有几个该类型组件实例,调用几次
  • render方法:1+n次,1是初始化时调用,n为状态更新次数

6 state简写

在日常开发中,我们怎么使用state呢?

需求说明:

  1. 我们只是想初始化转态
  2. 确保自定义方法中this指向组件实例

解决:

  1. 把state在类中方法外初始化
  2. 使用箭头函数

知识点:

  • 实例变量

    • 定义:实例变量是类中方法外的变量,不过没有static修饰,也叫对象变量(new出来的);或者构造方法this.XXX

    • 作用有效范围:实例变量在对象创建的时候创建,在对象被销毁的时候销毁;

    • 默认值:实例变量具有默认值。数值型变量的默认值是0,布尔型变量的默认值是false,引用类型变量的默认值是null。变量的值可以在声明时指定,也可以在构造方法中指定;

  • 箭头函数:箭头函数内部this为其外层所在区域的this。如果在类中为类的实例对象;否则为全局对象window。

简化代码如下,其他同上:

    // 1.类式组件
  class Weather extends React.Component {
    // 初始化state
    state = {isHot: false, wind: '微风'}

    render() {
      return <h2 onClick={this.changeWeather}>今天天气很{this.state.isHot ? '炎热' : '凉爽'},{this.state.wind}</h2>
    }
    // =赋值表示changeWeather是实例方法
    changeWeather = () => {
      this.setState({isHot: !this.state.isHot})
    }
   }

7 问题解答

  • 2.1-暂时给出官网参考,参考官网首页,如下图7-1所示:

    在这里插入图片描述

    • props是什么?下个篇章讲解props
  • 2.2 类的语法规定:如果B类继承A类,而A类中写了构造器,那么B类构造器中super必须要调用。

后记

❓QQ:806797785

⭐️源代码仓库地址:https://gitee.com/gaogzhen/react-study

参考:

[1]尚硅谷React教程(2022加更,B站超火react教程)[CP/OL].2020-12-15.p7-p19.

[2]JS中Class类的静态属性和静态方法[CP/OL].

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/391862.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在NVIDIA JetBot Nano小车上更新WIFI驱动

前言:树莓派上的WIFI驱动类型比较多&#xff0c;经常有更好驱动的需求本文给出RealTek的无线WIFI模组&#xff0c;8821CU的驱动更新办法步骤第一 通过其他方式连接网络小车通过网线或者老的WIFI连接到网络上第二 构建驱动模块并下载驱动首先&#xff0c;我们需要打开一个ubuntu…

【深度学习】BERT变体—RoBERTa

RoBERTa是的BERT的常用变体&#xff0c;出自Facebook的RoBERTa: A Robustly Optimized BERT Pretraining Approach。来自Facebook的作者根据BERT训练不足的缺点提出了更有效的预训练方法&#xff0c;并发布了具有更强鲁棒性的BERT&#xff1a;RoBERTa。 RoBERTa通过以下四个方面…

【JavaEE】基于mysql与servlet自制简易的表白墙程序

文章目录1 表白墙页面构建2 Servlet 回顾3 表白墙后端程序实现3.1 我们需要做什么&#xff1f;3.2 实现细节4 实现结果写在最后1 表白墙页面构建 该页面由标题、文本、三个 input 输入框与一个提交按钮构成&#xff0c;整体比较简单&#xff0c;相关样式文件和页面代码会在后面…

【16】linux命令每日分享——tail命令查看文件

大家好&#xff0c;这里是sdust-vrlab&#xff0c;Linux是一种免费使用和自由传播的类UNIX操作系统&#xff0c;Linux的基本思想有两点&#xff1a;一切都是文件&#xff1b;每个文件都有确定的用途&#xff1b;linux涉及到IT行业的方方面面&#xff0c;在我们日常的学习中&…

分布式中雪花算法

背景需要选择合适的方案去应对数据规模的增长&#xff0c;以应对逐渐增长的访问压力和数据量。 数据库的扩展方式主要包括&#xff1a;业务分库、主从复制&#xff0c;数据库分表。 2.数据库分表概念&#xff1a;将不同业务数据分散存储到不同的数据库服务器&#xff0c;能够支…

网络参考模型

OSI参考模型 应用层 不服务于任何其他层&#xff0c;就是位APP提供相应的服务&#xff0c;不如HTTP、域名解析DNS提供服务表示层 1.使得应用数据能够被不同的系统&#xff08;Windows\Linux&#xff09;进行识别和理解 2.数据的解码和编码、数据的加密与解密、数据的压缩和解…

简单易懂值得收藏的Spring源码解析,依赖注入和bean的初始化

简单易懂值得收藏的Spring源码解析&#xff0c;依赖注入和bean的初始化原理解析依赖注入PropertyValues、PropertyValue、PropertyAccessorbyNamebyTypeAutowiredbean的初始化源码走读依赖注入populateBean方法autowireByNameautowireByType方法AutowiredAnnotationBeanPostPro…

广义状态平均法功率变换器建模分析

两种状态平均法在功率变换器建模的应用比较 [!info] Bibliography [1] 高朝晖, 林辉张晓斌 & 吴小华, “两种状态平均法在功率变换器建模的应用比较,” 计算机仿真, no. 241-244248, 2008. [!note] 状态空间平均法采用直流量近似&#xff08;线性系统模型&#xff09;&…

通达信指标公式颜色代码的四种写法(COLOR/RGB)

通达信指标公式颜色代码有四种写法&#xff0c;分别为COLOR颜色的英文、COLOR十六进制、RGBX十六进制、RGB(R,G,B)。标题有点尴尬&#xff0c;让我想到孔乙己“茴”字的四种写法&#xff0c;哈哈。 一、COLOR颜色的英文 “COLOR颜色的英文”这种写法比较简单&#xff0c;函数库…

【C++】bsearch函数的使用及二分法查找介绍

写程序的时候&#xff0c;肯定避免不了需要从集合中找到符合条件的元素&#xff0c;一般情况下&#xff0c;最简单也最常用的就是循环遍历元素&#xff0c;这种方法虽然写的简单&#xff0c;但是小数据量还行&#xff0c;但是数据过大的话&#xff0c;这样效率就低了。循环的时…

浅谈游戏中运用到的人工智能

电子游戏中的人工智能意味着电子游戏中角色的创造性行为就像人类游戏玩家正在控制他们一样。它提供了自适应和响应式的视频游戏体验。1949年初&#xff0c;密码学家克劳德香农发现了游戏中的人工智能&#xff0c;从而联想到了电脑上的单人国际象棋游戏。对于人工智能的发展&…

Android的基础介绍

一、Android介绍 Android是一种基于Linux的自由及开放源代码的操作系统,Android 分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和Linux内核层。 Android 是Google开发的基于Linux平台的开源手机操作系统。它包括操作系统、用户界面和应用程序——…

力扣-可回收且低脂的产品

大家好&#xff0c;我是空空star&#xff0c;本篇带大家了解一道超级超级超级简单的力扣sql练习题。 文章目录前言一、题目&#xff1a;1757. 可回收且低脂的产品二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交S…

iview tree树形菜单实践之数据回显与选中

iview tree树形菜单在使用过程中&#xff0c;多多少少有一些小坑&#xff0c;本文简单罗列几个&#xff1a; 避坑指南&#xff1a; 关于iview tree树形菜单在使用过程中存在父级菜单的数据传输和回显问题 简单就是两个方面&#xff1a;勾选后数据传输和回显问题。 一&#xff…

mac 环境下安装MongoDB

目录 一、下载MongoDB数据库并进行安装 二. 解压放在/usr/local目录下 三. 配置环境变量 “无法验证开发者”的解决方法 mongodb可视化工具的安装与使用 一、下载MongoDB数据库并进行安装 下载地址&#xff1a;https://www.mongodb.com/try/download/community 二. 解压…

大数据项目实战之数据仓库:用户行为采集平台——第2章 项目需求及架构设计

第2章 项目需求及架构设计 2.1 项目需求分析 1&#xff09;采集平台 &#xff08;1&#xff09;用户行为数据采集平台搭建 &#xff08;2&#xff09;业务数据采集平台搭建 2&#xff09;离线需求 3&#xff09;实时需求 4&#xff09;思考题 1、项目技术如何选型&…

索引调优的一点基础知识

索引是什么 通过 show profile for query 1&#xff1b; 可以查看该查询语句执行的整个过程&#xff0c;则我们就能分析出那部分是需要优化的索引是帮助Mysql高效获取数据的数据结构 索引存储在文件系统中 索引的文件存储形式与存储引擎有关 索引文件的结构 hash 范围查找不方便…

深度学习-第T2周——彩色图片分类

深度学习-第T2周——彩色图片分类深度学习-第P1周——实现mnist手写数字识别一、前言二、我的环境三、前期工作1、导入依赖项并设置GPU2、导入数据集3、归一化4、可视化图片四、构建简单的CNN网络五、编译并训练模型1、设置超参数2、编写训练函数六、预测七、模型评估深度学习-…

产品经理如何去做需求分析,建议收藏

目录 一、需求收集 1. 产品需求 2. 功能需求 3. 迭代需求 二、需求分析 1. 系统了解需求&#xff08;5W2H法&#xff09; 2. 判断需求真实性 3. 分析现有解决方案-竞品分析 4. 行业结构分析 5. 总结 三、方案验证 四、商业模式 五、路线规划 六、战略制定 七、总…

基于贝叶斯优化CNN-LSTM混合神经网络预测(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密…