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

本文主要是介绍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 对并增加索引值。

这篇关于React自定义Componment和State深层次理解-07的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1006772

相关文章

Python将博客内容html导出为Markdown格式

《Python将博客内容html导出为Markdown格式》Python将博客内容html导出为Markdown格式,通过博客url地址抓取文章,分析并提取出文章标题和内容,将内容构建成html,再转... 目录一、为什么要搞?二、准备如何搞?三、说搞咱就搞!抓取文章提取内容构建html转存markdown

在React中引入Tailwind CSS的完整指南

《在React中引入TailwindCSS的完整指南》在现代前端开发中,使用UI库可以显著提高开发效率,TailwindCSS是一个功能类优先的CSS框架,本文将详细介绍如何在Reac... 目录前言一、Tailwind css 简介二、创建 React 项目使用 Create React App 创建项目

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方

使用Sentinel自定义返回和实现区分来源方式

《使用Sentinel自定义返回和实现区分来源方式》:本文主要介绍使用Sentinel自定义返回和实现区分来源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Sentinel自定义返回和实现区分来源1. 自定义错误返回2. 实现区分来源总结Sentinel自定

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方

如何自定义Nginx JSON日志格式配置

《如何自定义NginxJSON日志格式配置》Nginx作为最流行的Web服务器之一,其灵活的日志配置能力允许我们根据需求定制日志格式,本文将详细介绍如何配置Nginx以JSON格式记录访问日志,这种... 目录前言为什么选择jsON格式日志?配置步骤详解1. 安装Nginx服务2. 自定义JSON日志格式各

css中的 vertical-align与line-height作用详解

《css中的vertical-align与line-height作用详解》:本文主要介绍了CSS中的`vertical-align`和`line-height`属性,包括它们的作用、适用元素、属性值、常见使用场景、常见问题及解决方案,详细内容请阅读本文,希望能对你有所帮助... 目录vertical-ali

Android自定义Scrollbar的两种实现方式

《Android自定义Scrollbar的两种实现方式》本文介绍两种实现自定义滚动条的方法,分别通过ItemDecoration方案和独立View方案实现滚动条定制化,文章通过代码示例讲解的非常详细,... 目录方案一:ItemDecoration实现(推荐用于RecyclerView)实现原理完整代码实现

浅析CSS 中z - index属性的作用及在什么情况下会失效

《浅析CSS中z-index属性的作用及在什么情况下会失效》z-index属性用于控制元素的堆叠顺序,值越大,元素越显示在上层,它需要元素具有定位属性(如relative、absolute、fi... 目录1. z-index 属性的作用2. z-index 失效的情况2.1 元素没有定位属性2.2 元素处

Python实现html转png的完美方案介绍

《Python实现html转png的完美方案介绍》这篇文章主要为大家详细介绍了如何使用Python实现html转png功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 1.增强稳定性与错误处理建议使用三层异常捕获结构:try: with sync_playwright(