React自定义Componment和State深层次理解-07

本节主要从底层原理上分析下React开发相关的内容和注意事项,本节会围绕使用展开,而非源码讲解。

Componment详解

什么是组件

在 MVVM架构出现之前,组件主要分为两种。

  • 狭义上的组件,又称为 UI 组件,比如 Tabs 组件、Dropdown 组件。组件主要围绕在交互动作上的抽象,针对这些交互动作,利用 JavaScript 操作 DOM 结构或 style
    样式来控制。这样的逻辑一旦复杂,就存在大量的 DOM 操作,开发及维护成本相当高。
  • 广义上的组件,即带有业务含义和数据的 UI 组件组合。这类组件不仅有交互动作,更重 要的是有数据与界面之间的交互。然而,这类组件往往有较大的争议。在规模较大的场景下,我们更倾向于采用分层的思想去处理。

React 的本质核心关心元素的构成, React 组件也可理解为组件元素。组件元素被描述成纯粹的 JSON 对象,意味着可以使用方法或是类来构建。React 组件基本上由 3 个部分组成:属性(props)、状态(state)以及生命周期方法。

组件的生命周期

  • 下图是一个详细的数据流图:
    在这里插入图片描述
  • 对上图进行不同阶段的分解后,不同操作执行过程如下表所示:
First RenderUnmoutPropes changeState change
getDefaultPropscomponentWillUnMountcomponentWillReceivePropsshouldComponentUpdate
getInitialStaterendershouldComponentUpdatecomponentWillUpdate
componentWillMountgetInitialStatecomponentWillUpdaterender
rendercomponentWillMountrendercomponentDidUpdate
componentDidMountcomponentDidMountcomponentDidUpdate
  • 原码方法详解如下:(需要注意,不同版本的React方法可能不太一样)
/*组件再次渲染时,在render()渲染前调用,即props和state发生变化时会触发此方法*/
componentWillUpdate: function () {
},/*组件再次渲染时,在render()渲染后调用*/
componentDidUpdate: function () {
},/*在新节点插入DOM结构之前调用*/
componentWillMount: function () {
},/*在新节点插入DOM结构之后调用*/
componentDidMount: function () {
},/*在组件从DOM中移除时调用*/
componentWillUnmount: function () {
},/*在componentWillUpdate()之前调用,用来决定组件是否调用render()来更新,返回true和false*/
shouldComponentUpdate(nextProps, nextState){
}

在这里插入图片描述

创建组件的步骤

  • 以下是一个指引,在使用熟练之外基本不用参考如下图流程。
    在这里插入图片描述
  • 在构造大型组件时一是要考虑复用、二是要考虑其可跳跃性,所以一般会以树状结构构建,详细的例子可参考 将 UI 视为树
    在这里插入图片描述

用分离模式来设计组件

虽然可以把一个组件的所有代码写在一个.js文件中,但这种方法的复用度不是太好,所以一般要设计大型组件时一般会采用分离设计:数据+UI数据+UI+包装器,这种设计方式主要依赖了React的:

  1. props这种可以共享数据的机制;
  2. 、组件调用时可以传递子元素的属性(是一个children数组)。
    比如下例:

定义UI组件

这里只关注样式,没有状态数据

import React from 'react'const Geolocation = ({ latitude, longitude }) => (<div><div>Latitude: {latitude}</div><div>Longitude: {longitude}</div></div>
)Geolocation.propTypes = {latitude: React.PropTypes.number,longitude: React.PropTypes.number,
}export default Geolocation

定义UI容器

包装了UI组件,同时所有的状态全在这里进行处理

import React from 'react'
import Geolocation from './geolocation'class GeolocationContainer extends React.Component {constructor(props) {super(props)this.state = {latitude: null,longitude: null,}this.handleSuccess = this.handleSuccess.bind(this)}handleSuccess({ coords }) {this.setState({latitude: coords.latitude,longitude: coords.longitude,})}render() {return ( //此处包装<Geolocation {...this.state} />)}
}export default GeolocationContainer

保持组件的纯粹

React 便围绕着这个概念进行设计。React 假设你编写的所有组件都是纯函数。也就是说,对于相同的输入,你所编写的 React 组件必须总是返回相同的 JSX。简单理解一下就是上面所说的UI和操作分离的情况。比如下面的例子:

function Cup() {// Bad:正在更改预先存在的变量!,最好把guest做为Cup的一个参数guest = guest + 1;return <h2>Tea cup for guest #{guest}</h2>;
}export default function TeaSet() {return (<><Cup /><Cup /><Cup /></>);
}

这种作法有助于:

  • 组件可以在不同的环境下运行 — 例如,在服务器上!由于它们针对相同的输入,总是返回相同的结果,因此一个组件可以满足多个用户请求。
  • 可以为那些输入未更改的组件来 跳过渲染,以提高性能。这是安全的做法,因为纯函数总是返回相同的结果,所以可以安全地缓存它们。
  • 如果在渲染深层组件树的过程中,某些数据发生了变化,React 可以重新开始渲染,而不会浪费时间完成过时的渲染。纯粹性使得它随时可以安全地停止计算。

组件渲染的时机

有两种原因会导致组件的渲染:

  1. 组件的 初次渲染。在进行初次渲染时, React 会调用根组件。
  2. 组件(或者其祖先之一)的 状态发生了改变。对于后续的渲染, React 会调用内部状态更新触发了渲染的函数组件。

这个过程是递归的:如果更新后的组件会返回某个另外的组件,那么 React 接下来就会渲染 那个 组件,而如果那个组件又返回了某个组件,那么 React 接下来就会渲染 那个 组件,以此类推。这个过程会持续下去,直到没有更多的嵌套组件并且 React 确切知道哪些东西应该显示到屏幕上为止。

基于以上,也是为什么要保持组件纯粹的原因了,因为这关乎性能。

State详解

这东西到底干啥用的呢,本质上React也是一个MVVM的实现(核心是一个有状态的组件),虽然可以通过传统的方式来实现数据改变时的UI样式,但会比较麻烦,所以React给每个组件加了一个state功能,通过state来实现数据和展现的互动,其原理简单理解如下:
在这里插入图片描述

state 机制目的是代替原有的props机制实现数据和视图的绑定。setState(),方法可接受一个Object参数,内部会把此参数和原state数据进行合并。

setState()

语法格式:setState({}, callBack)

一般在使用React开发组件时,建议选择受控组件开发,然后通过控制state进而控制render()方法的调用,用这种方式来取代非受控组件的开发模式。

比如:在下例中input 绑定一个 change 事件,每当表单的状态发生变化时,都会被写入到组件的 state 中,这种组件在 React 中被称为受控组件(controlled component)。在受控组件中,React 通过这种方式消除了组件的局部状态,使得应用的整个状态更加可控, React 受控组件更新 state 的流程:

  1. 可以通过在初始 state 中设置表单的默认值。
  2. 每当表单的值发生变化时,调用 onChange 事件处理器。
  3. 事件处理器通过合成事件对象 e 拿到改变后的状态,并更新应用的 state。
  4. setState 触发视图的重新渲染,完成表单组件值的更新。
class App extends React.Component {constructor(props) {super(props);this.handleInputChange = this.handleInputChange.bind(this);this.state = {inputVal: 'male', //默认值};}handleInputChange(e) {this.setState({inputVal: e.target.value,});}render() {const { inputVal} = this.state;return (<div><input type="radio" value="male" checked={inputVal === 'male'} onChange={this.handleInputChange}/></div>);}}

其底层原理是,在 React 内部,为每个组件保存了一个数组,其中每一项都是一个 state 对。它维护当前 state 对的索引值,在渲染之前将其设置为 “0”。每次调用 useState 时,React 都会为你提供一个 state 对并增加索引值。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PC端应用订阅SDK接入攻略

本文档介绍了联想应用联运sdk接入操作指南&#xff0c;您可在了解文档内容后&#xff0c;自行接入应用联运sdk。 1. 接入前准备 1. 请先与联想商务达成合作意向。 2. 联系联想运营&#xff0c;提供应用和公司信息&#xff0c;并获取商户id、app id、key&#xff08;公私钥、…

Linux定时计划

定时计划 一、计划任务种类 突发性&#xff1a;临时决定只执行一次的任务 at&#xff1a;处理执行一次任务就结束定时性&#xff1a;每隔一定时间需要重复执行此命令 crontab&#xff1a;指定任务&#xff0c;按照设定的周期一直循环执行二、作用 定时任务可以用于自动备份…

如何将Windows PC变成Wi-Fi热点?这里提供详细步骤

序言 Windows 10和Windows 11都有内置功能,可以将你的笔记本电脑(或台式机)变成无线热点,允许其他设备连接到它并共享你的互联网连接。以下是操作指南。 由于Windows中隐藏的虚拟Wi-Fi适配器功能,你甚至可以在连接到另一个Wi-Fi网络或无线路由器时创建Wi-Fi热点,通过另…

Navicat 连接 OceanBase 快速入门 | 社区版

Navicat Premium&#xff08;16.1.9或更高版本&#xff09;正式支持 OceanBase全线数据库产品。OceanBase为现代数据架构打造的开源分布式数据库。兼容 MySQL 的单机分布式一体化国产开源数据库&#xff0c;具有原生分布式架构&#xff0c;支持金融级高可用、透明水平扩展、分布…

分布式音乐播放器适配了Stage模型

OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;应用开发自API 8及其更早版本一直使用的是FA模型进行开发。FA模型是Feature Ability的缩写&#xff0c;它和PA&#xff08;Particle Ability&#xff09;两种类型是过往长期推广的术语&#xff0c;深入人心…

95.网络游戏逆向分析与漏洞攻防-ui界面的设计-ui的设计与架构

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果&#xff0c;代码看不懂是正常的&#xff0c;只要会抄就行&#xff0c;抄着抄着就能懂了 内容…

精品丨快速申请免费https证书

https域名证书对提高网站排名有一定的好处&#xff0c;所以当今很多企业为了给网站一个好的安全防护&#xff0c;就会去申请该证书。如今很多企业虽然重视网站的安全防护&#xff0c;但是也重视成本&#xff0c;所以为了节约成本会考虑申请免费的https证书。 第一个好处 企业不…

用Prometheus全面监控MySQL服务:一篇文章搞定

简介 在现代应用中&#xff0c;MySQL数据库的性能和稳定性对业务至关重要。有效的监控可以帮助预防问题并优化性能。Prometheus作为一款强大的开源监控系统&#xff0c;结合Grafana的可视化能力&#xff0c;可以提供全面的MySQL监控方案。 设置Prometheus 安装Prometheus 使…

机器学习预测-CNN手写字识别

介绍 这段代码是使用PyTorch实现的卷积神经网络&#xff08;CNN&#xff09;&#xff0c;用于在MNIST数据集上进行图像分类。让我一步步解释&#xff1a; 导入库&#xff1a;代码导入了必要的库&#xff0c;包括PyTorch&#xff08;torch&#xff09;、神经网络模块&#xff0…

queue学习

std::queue 类是一种容器适配器&#xff0c;它提供队列的功能——尤其是 FIFO&#xff08;先进先出&#xff09;数据结构。此类模板用处为底层容器的包装器——只提供特定的函数集合。queue 在底层容器尾端推入元素&#xff0c;从首端弹出元素。 元素访问 front 访问第一个元素…

Shell环境变量深入:自定义系统环境变量

Shell环境变量深入&#xff1a;自定义系统环境变量 目标 能够自定义系统级环境变量 全局配置文件/etc/profile应用场景 当前用户进入Shell环境初始化的时候会加载全局配置文件/etc/profile里面的环境变量, 供给所有Shell程序使用 以后只要是所有Shell程序或命令使用的变量…

0基础认识C语言

为了给0基础一个舒服的学习路径&#xff0c;就有了这个专栏希望带大家一起进步。 话不多说&#xff0c;开始正题。 一、C语言的一段小历史 C语言的设计要追溯到20世纪60年代末和70年代初&#xff0c;在那个时代美国有这么一号人叫做丹尼斯.里奇&#xff0c;他和同事肯.汤普逊…

【vue】el-select选择器实现宽度自适应

选择器的宽度根据内容长度进行变化 <div class"Space_content"><el-selectv-model"value":placeholder"$t(bot.roommessage)"class"select"size"small"style"margin-right: 10px"change"selectcha…

【MySQL】库的基础操作

&#x1f30e;库的操作 文章目录&#xff1a; 库的操作 创建删除数据库 数据库编码集和校验集 数据库的增删查改       数据库查找       数据库修改 备份和恢复 查看数据库连接情况 总结 前言&#xff1a;   数据库操作是软件开发中不可或缺的一部分&#xff0…

若依框架对于后端返回异常后怎么处理?

1、后端返回自定义异常serviceException 2、触发该异常后返回json数据 因为若依对请求和响应都封装了&#xff0c;所以根据返回值response获取不到Code值但若依提供了一个catch方法用来捕获返回异常的数据 3、处理的方法

如何利用已有数据对模型进行微调

1.langchain整合llm做知识问答 利用LangChain的能力来结合检索和生成&#xff0c;形成一个知识增强的问答系统&#xff08;不涉及对模型的微调&#xff09;&#xff0c;而是利用llm从文档检索到问题解答。 langchain整合llm做知识检索 2.微调llm模型 1、首先是我们的数据集&…

python数据分析——数据可视化(图形绘制)

数据可视化&#xff08;图形绘制基础&#xff09; 前言一、图形绘制基础Matplotlib简介使用过程sin函数示例 二、常用图形绘制折线图的绘制plot示例 散点图的绘制scatter()示例 柱状图的绘制bar示例 箱型图绘制plot.box示例 饼状图的绘制pie示例 三、图形绘制的组合情况多个折线…

HTML静态网页成品作业(HTML+CSS)——宠物狗介绍网页(3个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有3个页面。 二、作品演示 三、代…

HCIP-Datacom-ARST自选题库__BGP判断【20道题】

1.传统的BGP-4只能管理IPV4单播路由信息&#xff0c;MP-BGP为了提供对多种网络层协议的支持&#xff0c;对BGP-4进行了扩展。其中MP-BGP对IPv6单播网络的支持特性称为BGP4&#xff0c;BGP4通过Next Hop属性携带路由下一跳地址信息。 2.BGP4通过Update报文中的Next Hop属性携带…

大模型额外篇章二:基于chalm3或Llama2-7b训练酒店助手模型

文章目录 一、代码部分讲解二、实际部署步骤(CHALM3训练步骤)1)注册AutoDL官网实名认证2)花费额度挑选GPU3)准备实验环境4)开始执行脚本5)从浏览器访问6)可以开始提问7)开始微调模型8)测试训练后的模型三、基于Llama2-7b的训练四、额外补充1)修改参数后2)如果需要访问…