【react全家桶学习】react中组件定义及state属性(超详/必看)
函数式组件定义及特点
定义(核心就是一个函数,返回虚拟dom):
import React from 'react'export default function index() {return <div>index</div>
}
特点:
- 1、适用于【简单组件】的定义
- 2、是一个函数,返回虚拟dom
- 3、函数名就是组件名
类式组件的定义及特点
学习之前可以先复习一下类相关的知识:
ES6--class类(详解/看完必会)_class es6_suoh's Blog的博客-CSDN博客
或者通过下面代码复习要用到的类的知识点(认真看、有帮助):
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>/*** 总结:* 1、类中的构造器不是必须写的,要对实例进行一些初始化的操作,如添加指定属性时才写* 2、如果A类继承了B类,且A类中写了构造器,那么A类构造器中的super是必须要调用的* 3、类中所定义的方法,都是放在了类的原型对象上,供实例使用*/// 创建一个Person类class Person {// 构造器方法,接收参数constructor(name, age) {// 构造器中的this是谁?---是类的实例对象(p1/p2)this.name = namethis.age = age}// 一般方法speak() {// speak方法放在了哪里?--Person的原型对象上,供实例使用// 通过Person实例(p1/p2)调用speak时,speak中的this就是Person实例console.log(`我的名字是${this.name},我的年龄是${this.age}~`)}}// 创建一个Person的实例对象const p1 = new Person("小锁", 19)const p2 = new Person("小索", 20)p1.speak() //实例p1调用Person类原型链上的方法speakp2.speak() //实例p2调用Person类原型链上的方法speakp1.speak.call({a: 1,b: 2}) //使用call调用改变this指向,传的是谁,this就指向谁// 创建一个Student类,继承于Person类class Student extends Person {// 这里不需要接收s1传过来的姓名和年龄参数,因为我们继承了Person,// Person里面接收了这两个参数,下面我们只需要接收年级就好了constructor(name, age, grade) {// 下面写法不可取,因为属性多的时候,会和父类的赋值重复非常冗余// this.name = name// this.age = age// 因此我们利用super关键字,帮助我们在子类中调用父类// 将父类接收的2个参数传递过去即可// 注意:super关键字必须写在最前面,不能处于this.grade = grade之后super(name, age)this.grade = grade}// 重写从父类继承过来的方法speak() {console.log(`我的名字是${this.name},我的年龄是${this.age},我的年级是${this.grade}~`)}// 一般方法study() {// study方法放在了哪里?--类的原型对象上,供实例使用// 通过Student实例s1调用speak时,speak中的this就是Student实例console.log(`我的名字是${this.name},我的年龄是${this.age}~`)}}const s1 = new Student('小美', 19, '大学')console.log(s1)// 如果自身不存在学生也能访问到父类的speak方法,原型链的原因s1.speak()</script>
</body></html>l
特点:
- 1、适用于【复杂组件】的定义
- 2、组件是用类定义的,随后new出来该类的实例,并通过该实例调用到原型上的render方法
- 3、将render返回的虚拟dom转为真实dom,呈现在页面中
定义方式:
import React, { Component } from 'react'
// 创建类式组件
export default class index extends Component {// render是放在哪里的?--在index组件的原型对象上,供实例使用// render的this是谁?--在index组件的实例对象(index组件实例对象)render() {console.log(this)return <div>index</div>}
}
我们打印一下this,输出的是组件的实例对象。
补充1:什么是复杂组件?
复杂组件:就是有状态(state)的组件就叫复杂组件
除了使用外部数据 (通过 this.props 访问)以外,组件还可以维护其内部的状态数据 (通过 this.state 访问)。当组件的状态数据改变时,组件会再次调用 render() 方法重新染对应的标记。
补充2:什么是 state(状态)?
- state 是组件对象最重要的属性,值是对象(可以包含多个 key-value 的组合)
- 组件被称为"状态机"通过更新组件的 state 来更新对应的页面显示(重新染组件)
- react 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。
state中的值可以修改,修改的唯一方法是调用 this.setState(后面会讲) ,每次修改以后,自动调用 this.render 方法,再次渲染组件。
(也就是说直接
this.state.num = 2
这样直接修改值是无效的)
state在组件的构造函数中赋值
举个例子,让页面根据state中的值来进行变化。
假如我们想给state里面放入一个week参数,注意:state 的值是对象(可以包含多个 key-value 的组合),步骤如下
可以看到,传入成功
读取state的值,直接this.state.xxx即可
也可以利用解构赋值简化代码
那我们想要通过点击事件动态改变这个属性如何处理?下面来讲react中的事件绑定
补充3:react中的事件绑定
react中的事件绑定呢,跟原生js及其相似,只不过在原生的基础上添加了一点点区别、
例如事件命名方式:原生onclick -->react是onClick 、原生onblur -->react是onBlur等。
- React事件的命名采用的是小驼峰式, 例如(onClick),而不是纯小写(onclick)
- 使用JSX语法的时候,需要传入一个函数作为事件处理函数,而不是一个字符串
试一下:
页面报错了,看来用个字符串确实不行,
翻译过来,说是onClick必须是个函数而不是字符串
好吧。挺多事的、看来得用花括号包裹,才能保证他是一个函数
法一:点击事件写在render里面
注意:如果在标签的函数里面直接添加了小括号,那么他就会一上来就开始调用。
因此需要把小括号去掉,这样就完美了~
这时有人可能会发现,我上面函数 testFunc的定义 是位于render里面。
法二:当然还有一种写法,就是将函数写在外面(推荐),两者的区别往下看
补充4:react事件函数写在render里外的区别
React的事件函数可以写在render里外,但是它们的区别在于:
- 1、写在render里的事件函数可以跟随渲染周期每次重新实例化,这样可以保证它们的最新状态;而写在render外的事件函数只在第一次加载时被实例化,不能保证最新状态。
- 2、写在render里的事件函数可以被重新实例化,可以保证它们具有最新的props和state;而写在render外的事件函数只能获取它们在第一次加载时的props和state,不能保证最新的props和state。
- 3、写在render里的事件函数可以和render的内容组合在一起,可以实现更好的可读性和维护性;而写在render外的事件函数可以使代码结构更加清晰,可以使代码更易读。
- 4、写在render里的事件函数需要加上function,且调用时需要加上this;写在render外的事件函数不需要加function,调用时也不需要加this。
- 5、由于在render里调用this.setState事件会陷入死循环(原因是参考博主:react 中千万不要在render里调用this.setState_render里面写setstate_小刘先生很努力的博客-CSDN博客)。因此我们在大部分场景中还是推荐写在render外。
总之,写在render里和写在render外的事件函数各有优缺点,在使用时要根据实际情况来选择。
问题来了,现在我们已经可以实现点击事件了,那我想在点击的时候改变state中的week值,如何写?有人说直接赋值就好了呀
看下效果:当我点击的一下之后报错了,说state未定义,这说明通过this没找到state呀。
大胆推测:this指向出现了问题。
补充5:如何修改类中方法的this指向
那构造器的this以及render中的this均指向index组件实例,怎么就函数的this出现了undefined?
(1)因为类中定义的方法已经在局部开启了严格模式,
(2)只有通过实例调用的才会正常,而testFunc是作为onClick的回调,所以不是通过实例调用的,是直接调用,所以this指向为undefined
所以接下来我们只能改变this指向来让他指向index组件实例,如何解决?
改变this指向的方法有apply call 箭头函数 bind,都试下
call和apply都试了下,都是一上来就执行,所以不可行
注意:bind是返回对应函数,便于稍后调用;apply、call则是立即调用 。
还有箭头函数,文章后面代码精简的时候会讲解到
因此我们得用bind
重点是这一句:this.testFunc = this.testFunc.bind(this) 代表的含义就是,将原型上的testFunc函数通过bind改变this指向(使其指向index组件实例)返回一个新的函数重新赋值给testFunc函数,这样testFunc函数的this指向就正常了、
此时就打印出正常的this信息了、
补充6:解决了this指向,如何通过this去改变state中数据的值?
解决了this指向,我们重新在方法中访问state值就不会报错了。
state值修改成功了?可页面怎么没变???
注意:不可以直接对state中的数据直接进行修改(this.state.week = '周二' 【错误写法】)。要借助内置API【setState】进行修改
这样就正常了、
补充7:contructor调用几次?render调用几次?
答: contructor只调用一次,render会调用1+n次 (1是初始化的那次,n是状态更新的次数)
小总结:
1、构造器的作用
- 初始化状态
- 解决类方法的this指向问题
2、render的作用
- 从状态state里面读取数据
- 根据状态进行页面展示
代码简化一:
在上面的关于类的复习里面已经讲了,构造器的作用主要是用于接收外部传进来的参数,当我们不需要接收外部传进来的值时是可以不用构造器的。而且需要注意:类中是可以直接写赋值语句的,但不能随意写代码,类始终不是函数体,函数体中可以定义变量、打印等,类中不允许
因此我们可以把构造器中的state赋值语句放入类中 ,代表给实例对象index追加了一个属性state
代码简化二:
当函数特别多的时候,我们可能会再构造器中写多个改变this指向的语句,十分冗余
改变this指向的方法还有一个是箭头函数、、、、
这样构造器就可以删了,简化之后
import React, { Component } from 'react'
// 创建类式组件
export default class index extends Component {// 初始化状态state = {week: '周一',}render() {const { week } = this.statereturn <h2 onClick={this.testFunc}>今天才{week}!</h2>}// 自定义方法--要用赋值语句的形式+箭头函数testFunc = () => {this.setState({week: '周二',})}
}
终于结束了,这是一个更改react组件页面上的数据引发的一系列问题讲解。希望大家可以认真阅读,绝对有帮助~
相关文章:

【react全家桶学习】react中组件定义及state属性(超详/必看)
函数式组件定义及特点 定义(核心就是一个函数,返回虚拟dom): import React from reactexport default function index() {return <div>index</div> }特点: 1、适用于【简单组件】的定义2、是一个函数&a…...

如何以产品经理思维打造一所高品质学校?
学校的建设与管理真不是一件容易事。2023年03月17日,山东菏泽市曹县一家长投诉某中学课业繁重,孩子经常写作业到半夜;2023年4月4日,张先生在华龙网重庆网络问政平台投诉万州区某中学伙食差,指出“发灰的洋葱࿰…...

根治Spring中使用Mongo时报错InvalidMongoDbApiUsageException
文章目录 And Or迷惑原因 告别InvalidMongoDbApiUsageException问题简单解决根本解决修改源码 代码(省流,可以直接看这里) And Or 很多时候都需要进行逻辑的与或操作,但是spring当中自带的操作并不好用,于是做了相关的改进&#…...

【计算机组成原理】数据的表示和运算·进位计数制
🚩 本文已收录至专栏:计算机基础 我们可以通过显示屏看到各种形式的数据信息,但数据是如何在计算机中表示呢?运算器又是如何实现数据的算数、逻辑运算? 十进制数是最适合我们日常使用的一种计数方式,除此之…...

C++ Primer第五版_第十四章习题答案(21~30)
文章目录 练习14.21练习14.22头文件CPP文件 练习14.23头文件CPP文件 练习14.24头文件CPP文件 练习14.25练习14.26练习14.27练习14.28练习14.29练习14.30 练习14.21 编写 Sales_data 类的 和 运算符,使得 执行实际的加法操作而 调用。相比14.3节和14.4节对这两个运…...

服务器性能调优
硬件 如果是硬件瓶颈就换硬件 (包括CPU、内存、网卡) 软件 如果是方案架构设计有问题就换方案,比如mysql、redis方案有问题 建议先 top 看下软件瓶颈在哪,CPU、内存、网络(netstat),哪个进程占…...

带你深入学习k8s--(三) pod 管理
目录 一、简介 1、什么是pod 2、为什么要有pod 二、pod的分类 0、pod常用命令命令 1、准备镜像 2、自主式pod 3、控制器创建pod 4、扩容pod数量 5、通过service暴露pod(负载均衡,自动发起) 6、更新应用版本 三、编写yaml文件 四、Pod生命周期…...

前端系列11集-ES6 知识总结
ES Module 优点 静态分析 浏览器和 Node 都支持 浏览器的新 API 能用模块格式提供 不再需要对象作为命名空间 export 用于规定模块的对外接口 输出的接口与其对应的值是动态绑定关系可以取到模块内部实时的值 import 用于输入其他模块提供的功能 具有提升效果,会提升…...

连接分析工具箱 | 利用CATO进行结构和功能连接重建
导读 本研究描述了一个连接分析工具箱(CATO),用于基于扩散加权成像(DWI)和静息态功能磁共振成像(rs-fMRI)数据来重建大脑结构和功能连接。CATO是一个多模态软件包,使研究人员能够运行从MRI数据到结构和功能连接组图的端到端重建,定制其分析并…...

【目标检测论文阅读笔记】Detection of plane in remote sensing images using super-resolution
Abstract 由于大量的小目标、实例级噪声和云遮挡等因素,遥感图像的目标检测精度低,漏检率或误检率高。本文提出了一种新的基于SRGAN和YOLOV3的目标检测模型,称为SR-YOLO。解决了SRGAN网络 对超参数的敏感性和模态崩溃问题。同时,Y…...

外卖app开发流程全解析
外卖app开发是现代餐饮业的一个必备部分。在这个数字化时代,人们更愿意使用手机应用程序来订购食品。因此,为了满足客户需求,餐饮企业需要开发自己的外卖app。 第一步:确定目标受众 在开始外卖app的开发之前,需要确定…...

BUUCTF jarvisoj_level0
小白垃圾做题笔记而已,不建议阅读。。。 这道题感觉主要就是64位程序ebp8 题目中给出了shellcode 我们直接将返回地址覆盖就好。 在main函数中调用了vulnerable_function()函数。 vulnerable函数是一个漏洞函数:(存在缓溢出),我们只需要将…...

网络安全之入侵检测
目录 网络安全之入侵检测 入侵检测经典理论 经典检测模型 入侵检测作用与原理 意义 异常检测模型(Anomaly Detection) 误用检测模型(Misuse Detection) 经典特征案例 编辑自定义签名 编辑 签名检查过程 检测生命周期…...

元数据管理
1、业务元数据 描述 ”数据”背后的业务含义主题定义:每段 ETL、表背后的归属业务主题。业务描述:每段代码实现的具体业务逻辑。标准指标:类似于 BI 中的语义层、数仓中的一致性事实;将分析中的指标进行规范化。标准维度…...

C# WebService的开发以及客户端调用
目录 1、WebService简介 1.1 什么是XML? 1.2 什么是Soap? 1.3 什么是WSDL? 2、WebService与WebApi的区别与优缺点 2.1 WebService与WebApi的区别: 2.2 WebService的优缺点: 2.3 WebApi的优缺点: 3…...

有符号数和无符号数左移和右移
主要是有符号数的左移。 有的说不管符号位,直接左移,所以可以一会正数一会复数 https://bbs.csdn.net/topics/391075092 有的说符号位不动,其他来左移 不明白了。。。。 https://blog.csdn.net/hnjzsyjyj/article/details/119721014 https://…...

Netty小白入门教程
一、概述 1.1 概念 Netty是一个异步的基于事件驱动(即多路复用技术)的网络应用框架,用于快速开发可维护、高性能的网络服务器和客户端。 1.2 地位 Netty在Java网络应用框架中的地位就好比,Spring框架在JavaEE开发中的地位。 以下的框架都使用了Nett…...

【逻辑位移和算数位移】
<< 运算符 && >> 运算符 正数位移 当 x>>n 中 x 为正数时,会将x的所有位右移x位,同时左边高位补0 显而易见,运算结束后,值为1 。 可知右移n位,结果就是 x / 2^n:7 / 2 ^2 1;…...

Blender3.5 边的操作
目录 1. 边操作1.1 边的细分 Subdivide1.2 边的滑移 Edge Slide1.3 边的删除1.4 边的溶解 Dissolve1.5 边线倒角 Bevel1.6 循环边 Loop Edges1.7 并排边 Ring Edges1.8 桥接循环边 1. 边操作 1.1 边的细分 Subdivide 在边选择模式,选中一条边,右键&…...

Java与Python、Node.js在人工智能和区块链应用程序开发中的比较
背景 Java、Python和Node.js都是常用的编程语言,它们在不同领域都有广泛的应用。在人工智能和区块链应用程序开发中,这三种语言都具有各自的优势和劣势。 Java的优势 Java在企业级应用中应用广泛,这得益于其跨平台性、安全性和稳定性等特点。在人工智能和区块链应用程序开…...

【计算机是怎么跑起来的】基础:计算机三大原则
【计算机是怎么跑起来的】基础:计算机三大原则 计算机的三个根本性基础1.计算机是执行输入,运算,输出的机器输入,运算,输出 2. 软件是指令和数据的集合指令数据 3. 计算机的处理方式有时与人们的思维习惯不同对计算机来…...

NXP公司LPC21XX+PID实现稳定温度控制
本例使用的是LPC21XX系列芯片提供的PWM功能实现稳定的温度控制。首先我们获得当前环境温度之后,再用设定的温度与当前温度相减,通过PID算法计算出当前输出脉宽,并将其输出到L298N模块中,使加热丝发热,形成闭环…...

【CE实战-生化危机4重置版】实现角色瞬移、飞翔
▒ 目录 ▒ 🛫 导读需求开发环境1️⃣ CE扫描内存,定位坐标地址(加密后的地址)2️⃣ 硬件写入断点,定位真实坐标地址内存写入断点,定位到访问地址分析代码...

强烈建议互联网人转战实体和农业,去了就是降维打击!实体太缺人才了,老板也不缺钱!...
大环境不好,互联网人该何去何从? 一位网友提出了一个新思路:强烈建议互联网同学转战实体、农业这些行业。实体真的太缺人才了,目前大部分实体都留下70后、80后在继续奋斗。其实实体老板很多都不缺钱,经过多年积累&…...

如何将 github pages 迁移到 vercel 上托管
如何将 github pages 迁移到 vercel 上托管 前言 早期网站使用 github pages,后来迁移到 coding,最近又放到腾讯云网站静态托管,无论是 coding 的 cos 存储桶,还是静态网站托管 他们都是收费的,那有没有免费的托管商呢,既不影响网站的访问速度还免费,于是,找了一下,还真有,ve…...

2023五一数学建模竞赛(五一赛)选题建议
提示:DS C君认为的难度:C<A<B,开放度:B<A<C 。 A题:无人机定点投放问题 这道题是传统的物理类题目,基本每次建模竞赛都会有。由于这道题目并未给明数据,所以数据获取和搜集资料是…...

Packet Tracer - 配置 RIPv2
Packet Tracer - 配置 RIPv2 目标 第 1 部分:配置 RIPv2 第 2 部分:验证配置 拓扑图 背景信息 尽管在现代网络中极少使用 RIP,但是作为了解基本网络路由的基础则十分有用。 在本活动中,您将使用适当的网络语句和被动接口配置…...

Android类似微信聊天页面教程(Kotlin)四——数据本地化
前提条件 安装并配置好Android Studio Android Studio Electric Eel | 2022.1.1 Patch 2 Build #AI-221.6008.13.2211.9619390, built on February 17, 2023 Runtime version: 11.0.150-b2043.56-9505619 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Windows 11 …...

C/C++基础知识
专栏:C/C 个人主页: C/C基础知识 前言C关键字(C98)命名空间命名空间的定义正常的命名空间的定义如何使用命名空间 命名空间可以嵌套同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中(一个工程中的.h文件和test.…...

Java 入门 - 语法基础
hello world public class Hello {public static void main(String[] args) {System.out.println("hello world");} } 复制代码 public: 是关键字;表示公开的class: 是关键字;用来定义类Hello: 是类名;大小写敏感;命名…...