React总结1

3 React技术

React是Facebook于2013年开源的框架。React解决的是前端MVC框架中的View视图层的问题。

3.1 Virtual DOM*

DOM(文档对象模型Document Object Model)
将网页内所有内容映射到一棵树型结构的层级对象模型上,浏览器提供对DOM的支持,用户可以是用脚本调用DOM API来动态的修改DOM结点,从而达到修改网页的目的,
这种修改是浏览器中完成,浏览器会根据DOM的改变重绘改变的DOM结点部分。
修改DOM重新渲染代价太高,前端框架为了提高效率,尽量减少DOM的重绘,提出了Virtual DOM,所有的修改都是现在VirtualDOM上完成的,通过比较算法,
找出浏览器DOM之间的差异,使用这个差异操作D0M,浏览器只需要渲染这部分变化就行了。

React实现了DOM Diff算法可以高效比对Virtual DOM和DOM的差异。

Virtual DOM实际上就是内存中的一个数据结构、对象,本身不属于浏览器,而是在浏览器中通过js引擎构建出来的一个对象。不管怎么样,都是在浏览器中跑得东西,和服务器端没什么关系。

前后端,一般前后端指的是web的前后端,前端往往指的是浏览器,后端指的是wsgi、server这些东西

前端技术,通常指浏览器中能够跑的东西:CSS,HTML,JS

3.2 支持JSX语法

JSX是一种JavaScript和XML混写的语法,是JavaScript的扩展。

React.render(<div><div><div>content</div></div></div>,document.getElementById('example')
)

3.3 测试程序

替换src/index.js程序

// 基于React框架,使用JSX语法,替换上述代码
// 1、导入react模块
import React from "react";  // 导入react模块
import ReactDOM from "react-dom";  // 导入react的DOM模块// 2、创建React元素
class Root extends React.Component{ // 组件类定义,从React.Component类上继承,这个类生成JSXElement对象,即React元素state = {p1: "www.baidu.",p2: "com"} // 每一个react组件component都有一个状态变量state,它是一个js对象,可以定义属性来保存值。如果状态发生变化,会触发UI重新渲染。state是组件内部的私有属性render(){ // 渲染函数,返回组件中渲染的内容, 注意,只能返回唯一一个顶级元素回去console.log("render log");setTimeout(() => this.setState({p2: "net"}), 3000); // 延时函数:设置异步修改状态  // state的变化,会触发调用render,所以,render内最好不要对state进行任何改变,虽然可以,但是尽量不要。// this.state.p2 = "net"return <div>{this.state.p1 + this.state.p2}</div>;  // div是一个容器,可以包含其他html标记。这里只能包含一个顶级元素}
}// 3、将React元素添加到DOM的Element元素中并渲染
ReactDOM.render(<Root/>, document.getElementById('root'));  // 渲染,将组件类挂载到DOM树中要被渲染的元素中去。第一个参数是JSXElement对象;第二个参数是DOM的Element元素。指定DOM树中被渲染的元素id,将React元素对DOM树中的元素进行替换并重新渲染。// 4、保存后文件自动编译
  • html中的元素分类:
    学习html后, 你会了解一些基本的html元素(Element), 如p, h1~h6, br, div, li, ul, img等.如果将这些元素细分, 又可以分别归为顶级 (top-level)元素,块级 (block-level)元素和内联 (inline)元素.

1、Top-level element 【顶级元素】: { html, body, frameset }。包括html, body, frameset, 表现如Block-level element, 属于高级块级元素.
2、Block-level element 【块级元素】: { p, h1~h6, div, ul }。顾名思义就是以块显示的元素,高度宽度都是可以设置的。比如我们常用的 p, h1~h6, div, ul 默认状态下都是属于块级元素。块级元素比较霸道,默认状态下每次都占据一整个行,后面的内容也必须再新起一行显示。当然非块级元素也可以通过css的 display:block;将其更改成块级元素。此外还有个特殊的,float也具有此功能。块级元素能够独立存在, 一般的块级元素之间以换行(如一个段落结束后另起一行)分隔。块级元素是构成一个html的主要和关键元素, 而任意一个块级元素均可以用Box model来解释说明.
3、Inline element 【内联元素】: { a, br, em, img, li, span }通俗点来说就是文本的显示方式,与块级元素相反,内联元素的高度宽度是不可以设置的,其宽度就是自身文字或者图片的宽度。我们常用到的<a>、<span>、<em>都属于内联元素。内联元素的显示特点就是像文本一样的显示,不会独自占据一个行。 当然内联元素也能变成块级元素,那就是通过css的display:inline;和float来实现。内联元素依附其他块级元素存在, 紧接于被联元素之间显示, 而不换行.

注意:
1、React组件的render函数return,只能是一个顶级元素。组件是最小封装对象
2、JSX语法是XML,要求所有元素闭合,注意<br />不能写成<br>

3.4 JSX规范*

首字母小写就是html标记,首字母大写就是组件。
要求严格的HTML标记,要求所有标签都必须闭合。br也应写成<br />,/前留一个空格。
单行省略小括号,多行请使用小括号
元素有嵌套,建议多行,注意缩进
JSX表达式:使用{}扩起来,如果大括号内使用了引号,会当做字符串处理。例如:<div>{'2>1?true:false'}<div/>


3.5 组件状态state*

每一个react组件component都有一个状态变量state,它是一个js对象,可以定义属性来保存值。
如果状态发生变化,会触发UI重新渲染。
state是组件内部的私有属性。

class Root extends React.Component{ // 组件类定义,从React.Component类上继承,这个类生成JSXElement对象,即React元素state = {p1: "www.baidu.",p2: "com"} // 每一个react组件component都有一个状态变量state,它是一个js对象,可以定义属性来保存值。如果状态发生变化,会触发UI重新渲染。state是组件内部的私有属性render(){ // 渲染函数,返回组件中渲染的内容console.log("render log");// this.setState({p2: "net"}); // 不可以对还在更新中的state使用setStatesetTimeout(() => this.setState({p2: "net"}), 3000); // 延时函数:设置异步修改状态,和上一行是两码事。// this.state.p2 = "net"return <div>{this.state.p1 + this.state.p2}</div>;  // div是一个容器,可以包含其他html标记。这里只能包含一个顶级元素}
}
  • state的变化,会触发调用render,所以,render内最好不要对state进行任何改变,虽然可以,但是尽量不要。
  • 延时函数:设置异步修改状态

3.6 复杂状态

将本目录中’./test.html’使用jsx进行替换。
可以将’./test.html’文件移动到上一层目录下,然后在浏览器中http://localhost:3000/test.html 进行访问查看效果。

class SubElement extends React.Component{render(){return <div>这是子元素SubElement</div>}
}class Trigger extends React.Component{state = {flag: true}handlerClick(event){console.log("触发的事件ID为:" + event.target.id)alert("点击这里触发事件,事件ID为" + event.target.id)this.setState({flag: !this.state.flag})}render(){let x = this.state.flag?'true':'false';return (<div id="trig" onClick={this.handlerClick.bind(this)}>定义一个html标记div,div是分组,给这个标记起名字ID为trig,并注册一个事件onClick,事件捆绑一个函数handlerClick函数.当鼠标点击时,触发事件。事件一被触发立即调用与该事件绑定的函数,同时送一个参数进去, 这个参数不用管,这个参数是浏览器对象(event对象),由浏览器自动传入<SubElement/>{x}</div>)}
}ReactDOM.render(<Trigger/>, document.getElementById("root2"))

3.7 props属性*

props,使得可以从外部给React组件传递数据。传入的这个数据如果是对象,还可以访问、修改对象的属性。
props的属性是只读的,不允许修改。

import React from "react";
import ReactDOM from "react-dom";class SubElement extends React.Component{render(){console.log(this.props.name)console.log(this.props.parent, 'SubElement.props.parent.state.flag=' + this.props.parent.state.flag) // 还可以通过props传递的对象,修改、访问外层对象的元素return <div>这是子元素SubElement {this.props.children} {/*演示通过子元素,给props的children元素增加的属性*/}</div>}
}class Trigger extends React.Component{state = {flag: true}handlerClick(event){alert("点击这里触发事件,事件ID为" + event.target.id)this.setState({flag: !this.state.flag})// this.props.name = "Trigger" // props元素只读,不允许修改}render(){let x = this.state.flag?'true':'false';return (<div id="trig" onClick={this.handlerClick.bind(this)}><SubElement name="我是subElement" parent={this}><hr /><div>我是subElement的children的元素</div> {/*演示通过子元素传入数据到props的children元素中*/}</SubElement>  {/*利用props属性,从组件外部给组件内部传递数据。这里的数据会保存到props属性中*/}点击这里触发一个事件,会弹出警告对话框。</div>)}
}ReactDOM.render(<Trigger/>, document.getElementById("root2"))

总结

  • state是私有private属性,组件外无法直接访问,可以修改state,建议使用setState。
  • props是公有public属性,组件外也可以访问,只读。
  • 代码示例中,name="我是subElement",这个属性作为单一对象传递给组件,加入到组件的props属性中;parent={this},这里的this是Trigger组件本身。
  • 在Trigger中,使用JSX语法增加子元素,这些子元素,也会被加入到subElement的props.children中

3.8 构造器constructor

ES6使用构造器,为组件添加属性

import React from "react";
import ReactDOM from "react-dom";class Trigger extends React.Component{// state = {flag: true}constructor(props){ /*ES6使用构造器,为组件添加属性。通过构造器添加属性,使代码可读性更好*/ super(props); // 调用父类的constructor,需传入props属性。this.state = {flag: true}}handlerClick(event){alert("触发事件的ID为" + event.target.id)this.setState({flag: !this.state.flag})}render(){return (<div>点击这里触发一个事件,会弹出警告对话框。</div>)}
}

3.9 组件的生命周期管理*

组件的声明周期可分为三个状态:

  • Mounting: 挂载,表示组件已插入到真实的DOM树中
  • Updating: 正在本重新渲染
  • Unmounting: 已从真实的DOM树中移除

组件的生命周期状态,说明在不同时机访问组件,组件正处在生命周期的不同状态上。在不同的声明周期状态访问,就产生不同的方法。

生命周期的方法如下:

  • 装载组件触发

    • componentWillMount 在渲染前调用,在客户端也在服务端。只会在装载之前调用一次。

    • componentDidMount:在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout,setInterval或者发送AJAX请求等操作(防止异部操作阻塞U1)。只在装载完成后调用一次,在render之后。

  • 更新组件触发。这些方法不会在首次render组件的周期调用

    • componentWillReceiveProps(nextProps)在组件接收到一个新的prop时被调用。这个方法在初始化render时不会被调用。

    • shouldComponentUpdate(nextProps,nextState)返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。

      可以在你确认不需要更新组件时使用。
      如果设置为false,就是不允许更新组件,那么componentWillUpdate、componentDidUpdate不会执行。

    • componentWillUpdate(nextProps, nextState)在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。

    • componentDidUpdate(prevProps,prevState)在组件完成更新后立即调用。在初始化时不会被调用。

  • 卸载组件触发

    • componentWillUnmount在组件从DOM中移除的时候立刻被调用。

在这里插入图片描述

从上图可以看出:

  • constructor构造器是最早被执行的函数
  • 要触发更新声明周期函数,需要更新stateprops

3.10 无状态组件*

从React15.0开始,支持无状态组件。定义为:

import React from "react";  // 导入react模块
import ReactDOM from "react-dom";  // 导入react的DOM模块function Root(props){return <div>{props.name}</div>;
}ReactDOM.render(<Root name={"test"}/>, document.getElementById("root"));

无状态组件也叫函数式组件。
开发中很多情况下,组件其实很简单,不需要state状态,也不需要使用生命周期函数。无状态组件很好的满足了需求。

  • 无状态组件函数应该提供一个参数props,返回一个React元素。
  • 无状态组件函数本身就是render函数。

改写定义代码为:

import React from "react";  // 导入react模块
import ReactDOM from "react-dom";  // 导入react的DOM模块let ROOT = props => <div>{props.name}</div>;
ReactDOM.render(<Root name={"test"}/>, document.getElementById("root"));

总结

react中,虚拟dom有可能会被文档。组件的state、props、生命周期一般都会被问,需要理解。

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

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

相关文章

62、SpringBoot 使用RestTemplate 整合第三方 RESTful 服务

这节的要点&#xff1a; 就是弄两个项目 &#xff0c; 从 端口9090 这个项目&#xff0c;通过 restTemplate&#xff0c; 去访问 端口8080 的项目&#xff0c;并获取8080项目的数据。 ★ RESTful服务包含两方面的含义 1. 自己的应用要暴露一些功能供别人来调用。此时我们是服…

Linux基本认识

一、Linux基本概念 Linux 内核最初只是由芬兰人林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;在赫尔辛基大学上学时出于个人爱好而编写的。 Linux 是一套免费使用和自由传播的类 Unix 操作系统&#xff0c;是一个基于 POSIX 和 UNIX 的多用户、多任务、支持多线程和多…

摄像头:输出图像YUV格式理论知识

本篇文章主要记录一下camera2输出摄像头的编码格式&#xff0c;及数据之间转换。本文章参考链接&#xff1a; https://blog.csdn.net/qq_39312146/article/details/129252235。 http://www.360doc.com/content/21/0522/14/17136639_978452591.shtml 只为了记录使用。 一、Came…

管理方法论:5. 团队发展的阶段模型——调整管理策略

概念 布鲁斯塔克曼(Bruce Tuckman)提出团队发展阶段模型。 团队发展的五个阶段是&#xff1a;组建期&#xff08;Forming&#xff09;、激荡期&#xff08;Storming&#xff09;、规范期&#xff08;Norming&#xff09;、执行期&#xff08;Performing&#xff09;和休整期&…

使用凌鲨进行聚合搜索

作为研发人员&#xff0c;我们经常需要在多个来源之间查找信息&#xff0c;以便进行研发工作。除了常用的搜索引擎如百度和必应之外&#xff0c;我们还需要查阅各种代码文档和依赖包等资源。这些资源通常分散在各个网站和文档库中&#xff0c;需要花费一定的时间和精力才能找到…

C++之生成详细汇编代码(二百一十六)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

前端JavaScript修饰器:简化代码,增强功能

​ &#x1f3ac; 岸边的风&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! ​ 目录 引言 1. 修饰器简介 2. 修饰器语法 3. 类修饰器 应用场景 示例代码 4. 方法修饰器 应用场景 示例代码 5. 属性…

webpack实战:最新QQ音乐sign参数加密分析

文章目录 1. 写在前面2. 接口抓包分析3. 扣webpack代码4. 补浏览器环境5. 验证加密结果 1. 写在前面 现在&#xff01;很多的网站使用Webpack加载和处理JS文件。所以对于使用了Webpack加载的JS代码&#xff0c;一旦它们被打包并在浏览器中执行&#xff0c;通常是难以直接阅读和…

CSS预编译:提升样式开发效率与可维护性的关键工具

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 引言 CSS预编译是一项前…

AMEYA360详解芯力特SIT1145AQ收发器芯片CAN FD Passive功能详解

01CAN FD Passive功能说明 芯力特在SIT1145AQ/FD版本中加入了CAN FD Passive功能&#xff0c;CAN FD Passive功能简单来说就是SIT1145AQ/FD在休眠或待机模式下屏蔽总线上的CAN FD报文。 为什么需要CAN FD Passive功能呢? SIT1145AQ的特定帧唤醒只支持CAN报文&#xff0c;当SIT…

跨域问题解决方案(三种)

Same Origin Policy同源策略&#xff08;SOP&#xff09; 具有相同的Origin&#xff0c;也即是拥有相同的协议、主机地址以及端口。一旦这三项数据中有一项不同&#xff0c;那么该资源就将被认为是从不同的Origin得来的&#xff0c;进而不被允许访问。 Cross-origin resource…

合宙Air724UG LuatOS-Air LVGL API控件-开关 (Switch)

开关 (Switch) 示例代码 function event_handler(obj, event)if event lvgl.EVENT_VALUE_CHANGED thenprint("State", lvgl.switch_get_state(obj))end endsw1 lvgl.switch_create(lvgl.scr_act(), nil) lvgl.obj_align(sw1, nil, lvgl.ALIGN_CENTER, 0, -50) lvg…