web前端教程分享React学习笔记(一),React的起源和发展:React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。

React与传统MVC的关系

轻量级的视图层库!A JavaScript library for building user interfaces

React不是一个完整的MVC框架,最多可以认为是MVC中的V(View),甚至React并不非常认可MVC开发模式;React 构建页面 UI 的库。可以简单地理解为,React 将将界面分成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,就成了我们的页面。

React高性能的体现:虚拟DOM

React高性能的原理:

在Web开发中我们总需要将变化的数据实时反应到UI上,这时就需要对DOM进行操作。而复杂或频繁的DOM操作通常是性能瓶颈产生的原因(如何进行高性能的复杂DOM操作通常是衡量一个前端开发人员技能的重要指标)。

React为此引入了虚拟DOM(Virtual DOM)的机制:在浏览器端用Javascript实现了一套DOM API。基于React进行开发时所有的DOM构造都是通过虚拟DOM进行,每当数据变化时,React都会重新构建整个DOM树,然后React将当前整个DOM树和上一次的DOM树进行对比,得到DOM结构的区别,然后仅仅将需要变化的部分进行实际的浏览器DOM更新。而且React能够批处理虚拟DOM的刷新,在一个事件循环(Event Loop)内的两次数据变化会被合并,例如你连续的先将节点内容从A-B,B-A,React会认为A变成B,然后又从B变成A UI不发生任何变化,而如果通过手动控制,这种逻辑通常是极其复杂的。

尽管每一次都需要构造完整的虚拟DOM树,但是因为虚拟DOM是内存数据,性能是极高的,部而对实际DOM进行操作的仅仅是Diff分,因而能达到提高性能的目的。这样,在保证性能的同时,开发者将不再需要关注某个数据的变化如何更新到一个或多个具体的DOM元素,而只需要关心在任意一个数据状态下,整个界面是如何Render的。

React Fiber:

在react 16之后发布的一种react 核心算法,React Fiber是对核心算法的一次重新实现(官网说法)。之前用的是diff算法。

在之前React中,更新过程是同步的,这可能会导致性能问题。

当React决定要加载或者更新组件树时,会做很多事,比如调用各个组件的生命周期函数,计算和比对Virtual DOM,最后更新DOM树,这整个过程是同步进行的,也就是说只要一个加载或者更新过程开始,中途不会中断。因为JavaScript单线程的特点,如果组件树很大的时候,每个同步任务耗时太长,就会出现卡顿。

React Fiber的方法其实很简单——分片。把一个耗时长的任务分成很多小片,每一个小片的运行时间很短,虽然总时间依然很长,但是在每个小片执行完之后,都给其他任务一个执行的机会,这样唯一的线程就不会被独占,其他任务依然有运行的机会。

React的特点和优势

1、虚拟DOM

我们以前操作dom的方式是通过document.getElementById()的方式,这样的过程实际上是先去读取html的dom结构,将结构转换成变量,再进行操作

而reactjs定义了一套变量形式的dom模型,一切操作和换算直接在变量中,这样减少了操作真实dom,性能真实相当的高,和主流MVC框架有本质的区别,并不和dom打交道

2、组件系统

react最核心的思想是将页面中任何一个区域或者元素都可以看做一个组件 component

那么什么是组件呢?

组件指的就是同时包含了html、css、js、image元素的聚合体

使用react开发的核心就是将页面拆分成若干个组件,并且react一个组件中同时耦合了css、js、image,这种模式整个颠覆了过去的传统的方式

3、单向数据流

其实reactjs的核心内容就是数据绑定,所谓数据绑定指的是只要将一些服务端的数据和前端页面绑定好,开发者只关注实现业务就行了

4、JSX 语法

在vue中,我们使用render函数来构建组件的dom结构性能较高,因为省去了查找和编译模板的过程,但是在render中利用createElement创建结构的时候代码可读性较低,较为复杂,此时可以利用jsx语法来在render中创建dom,解决这个问题,但是前提是需要使用工具来编译jsx

编写第一个react应用程序

react开发需要引入多个依赖文件:react.js、react-dom.js,分别又有开发版本和生产版本,create-react-app里已经帮我们把这些东西都安装好了。把通过CRA创建的工程目录下的src目录清空,然后在里面重新创建一个index.js. 写入以下代码:

// 从 react 的包当中引入了 React。只要你要写 React.js 组件就必须引入React, 因为react里有一种语法叫JSX,稍后会讲到JSX,要写JSX,就必须引入Reactimport React from 'react'// ReactDOM 可以帮助我们把 React 组件渲染到页面上去,没有其它的作用了。它是从 react-dom 中引入的,而不是从 react 引入。import ReactDOM from 'react-dom'​// ReactDOM里有一个render方法,功能就是把组件渲染并且构造 DOM 树,然后插入到页面上某个特定的元素上ReactDOM.render(// 这里就比较奇怪了,它并不是一个字符串,看起来像是纯 HTML 代码写在 JavaScript 代码里面。语法错误吗?这并不是合法的 JavaScript 代码, “在 JavaScript 写的标签的”语法叫 JSX- JavaScript XML。 <h1>欢迎进入React的世界</h1>,// 渲染到哪里 document.getElementById('root'))

元素与组件

如果代码多了之后,不可能一直在render方法里写,所以就需要把里面的代码提出来,定义一个变量,像这样:

import React from 'react'import ReactDOM from 'react-dom'// 这里感觉又不习惯了?这是在用JSX定义一下react元素const app = <h1>欢迎进入React的世界</h1>ReactDOM.render(

app,

document.getElementById('root'))

函数式组件

由于元素没有办法传递参数,所以我们就需要把之前定义的变量改为一个方法,让这个方法去return一个元素:

import React from 'react'import ReactDOM from 'react-dom'​// 特别注意这里的写法,如果要在JSX里写js表达式(只能是表达式,不能流程控制),就需要加 {},包括注释也是一样,并且可以多层嵌套const app = (props) => <h1>欢迎进入{props.name}的世界</h1>​ReactDOM.render(

app({

name: 'react'

}),

document.getElementById('root'))

这里我们定义的方法实际上也是react定义组件的第一种方式-定义函数式组件,这也是无状态组件。但是这种写法不符合react的jsx的风格,更好的方式是使用以下方式进行改造

import React from 'react'import ReactDOM from 'react-dom'​const App = (props) => <h1>欢迎进入{props.name}的世界</h1>​ReactDOM.render(

// React组件的调用方式 <App name="react" />,

document.getElementById('root'))

这样一个完整的函数式组件就定义好了。但要注意!注意!注意!组件名必须大写,否则报错。

class组件

ES6的加入让JavaScript直接支持使用class来定义一个类,react的第二种创建组件的方式就是使用的类的继承,ES6 class是目前官方推荐的使用方式,它使用了ES6标准语法来构建,看以下代码:

import React from 'react'import ReactDOM from 'react-dom'​class App extends React.Component {

render () {

return (

// 注意这里得用this.props.name, 必须用this.props <h1>欢迎进入{this.props.name}的世界</h1>

)

}}ReactDOM.render(

<App name="react" />,

document.getElementById('root'))

运行结果和之前完全一样,因为JS里没有真正的class,这个class只是一个语法糖, 但二者的运行机制底层运行机制不一样。

· 函数式组件是直接调用, 在前面的代码里已经有看到

· es6 class组件其实就是一个构造器,每次使用组件都相当于在实例化组件,像这样:

import React from 'react'import ReactDOM from 'react-dom'​class App extends React.Component {

render () {

return (

<h1>欢迎进入{this.props.name}的世界</h1>

)

}}​const app = new App({

name: 'react'}).render()​ReactDOM.render(

app,

document.getElementById('root'))

更老的一种方法

在16以前的版本还支持这样创建组件, 但现在的项目基本上不用

React.createClass({

render () {

return (

<div>{http://this.props.xxx}</div>

)

}})

组件的组合、嵌套

将一个组件渲染到某一个节点里的时候,会将这个节点里原有内容覆盖

组件嵌套的方式就是将子组件写入到父组件的模板中去,且react没有Vue中的内容分发机制(slot),所以我们在一个组件的模板中只能看到父子关系

// 从 react 的包当中引入了 React 和 React.js 的组件父类 Component// 还引入了一个React.js里的一种特殊的组件 Fragmentimport React, { Component, Fragment } from 'react'import ReactDOM from 'react-dom'​class Title extends Component {

render () {

return (

<h1>欢迎进入React的世界</h1>

)

}}class Content extends Component {

render () {

return (

<p>React.js是一个构建UI的库</p>

)

}}/** 由于每个React组件只能有一个根节点,所以要渲染多个组件的时候,需要在最外层包一个容器,如果使用div, 会生成多余的一层domclass App extends Component { render () { return ( <div> <Title /> <Content /> </div> ) }}**/// 如果不想生成多余的一层dom可以使用React提供的Fragment组件在最外层进行包裹class App extends Component {

render () {

return (

<Fragment>

<Title />

<Content />

</Fragment>

)

}}ReactDOM.render(

<App/>,

document.getElementById('root'))

#JSX 原理

要明白JSX的原理,需要先明白如何用 JavaScript 对象来表现一个 DOM 元素的结构?

看下面的DOM结构

<div class='app' id='appRoot'>

<h1 class='title'>欢迎进入React的世界</h1>

<p>

React.js 是一个帮助你构建页面 UI 的库

</p></div>

上面这个 HTML 所有的信息我们都可以用 JavaScript 对象来表示:

{

tag: 'div',

attrs: { className: 'app', id: 'appRoot'},

children: [

{

tag: 'h1',

attrs: { className: 'title' },

children: ['欢迎进入React的世界']

},

{

tag: 'p',

attrs: null,

children: ['React.js 是一个构建页面 UI 的库']

}

]}

但是用 JavaScript 写起来太长了,结构看起来又不清晰,用 HTML 的方式写起来就方便很多了。

于是 React.js 就把 JavaScript 的语法扩展了一下,让 JavaScript 语言能够支持这种直接在 JavaScript 代码里面编写类似 HTML 标签结构的语法,这样写起来就方便很多了。编译的过程会把类似 HTML 的 JSX 结构转换成 JavaScript 的对象结构。

下面代码:

import React from 'react'import ReactDOM from 'react-dom'​class App extends React.Component {

render () {

return (

<div className='app' id='appRoot'>

<h1 className='title'>欢迎进入React的世界</h1>

<p>

React.js 是一个构建页面 UI 的库

</p>

</div>

)

}}​ReactDOM.render(

<App />,

document.getElementById('root'))

编译之后将得到这样的代码:

import React from 'react'import ReactDOM from 'react-dom'​class App extends React.Component {

render () {

return (

React.createElement(

"div",

{

className: 'app',

id: 'appRoot'

},

React.createElement(

"h1",

{ className: 'title' },

"欢迎进入React的世界"

),

React.createElement(

"p",

null,

"React.js 是一个构建页面 UI 的库"

)

)

)

}}​ReactDOM.render(

React.createElement(App),

document.getElementById('root'))

React.createElement 会构建一个 JavaScript 对象来描述你 HTML 结构的信息,包括标签名、属性、还有子元素等, 语法为

React.createElement(

type,

[props],

[...children])

所谓的 JSX 其实就是 JavaScript 对象,所以使用 React 和 JSX 的时候一定要经过编译的过程:

JSX —使用react构造组件,bable进行编译—> JavaScript对象 — ReactDOM.render()—>DOM元素 —>插入页面

组件中DOM样式

· 行内样式

想给虚拟dom添加行内样式,需要使用表达式传入样式对象的方式来实现:

// 注意这里的两个括号,第一个表示我们在要JSX里插入JS了,第二个是对象的括号 <p style={{color:'red', fontSize:'14px'}}>Hello world</p>

行内样式需要写入一个样式对象,而这个样式对象的位置可以放在很多地方,例如render函数里、组件原型上、外链js文件中

· 使用class

React推荐我们使用行内样式,因为React觉得每一个组件都是一个独立的整体

其实我们大多数情况下还是大量的在为元素添加类名,但是需要注意的是,class需要写成className(因为毕竟是在写类js代码,会收到js规则的现在,而class是关键字)

<p className="hello" style = {this.style}>Hello world</p>

· 不同的条件添加不同的样式

有时候需要根据不同的条件添加不同的样式,比如:完成状态,完成是绿色,未完成是红色。那么这种情况下,我们推荐使用classnames这个包:

· css-in-js

styled-components是针对React写的一套css-in-js框架,简单来讲就是在js中写css。npm链接

TodoList

组件化开发React todolist, 项目开发中的组件的基本目录结构基本上是这样的:

注意:一个组件只干一件事情 ,所以TodoList和TodoItem要做成两个组件,这样也方便于后期理解shouldComponentUpdate

react render没更新_web前端教程分享React学习笔记(一)相关推荐

  1. 好程序员Web前端教程分享Vue学习心得

    为什么80%的码农都做不了架构师?>>>    好程序员Web前端教程分享Vue学习心得,Vue是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向 ...

  2. 正则至少一个数字_好程序员web前端培训分享JavaScript学习笔记之正则

    好程序员web前端培训分享JavaScript学习笔记之正则,正则表达式,又名 "规则表达式" 由我们自己来书写 "规则",专门用来检测 字符串 是否符合 &q ...

  3. vue 给取data值_web前端教程分享Vue相关面试题

    Vue是一套构建用户界面的渐进式框架,具有简单易用.性能好.前后端分离等优势,是web前端工程师工作的好帮手,也是企业选拔人才时考察的重点技能.接下来就给大家分享一些Vue相关的面试题,帮助大家提升竞 ...

  4. js怎么定义combobox_好程序员web前端教程分享新手应该怎么学习webpack

    好程序员web前端教程分享新手应该怎么学习webpack,什么是webpack?一句话概括:webpack是一个模块打包工具(module bundler).重点在于两个关键词"模块&quo ...

  5. react组件卸载调用的方法_好程序员web前端培训分享React学习笔记(三)

    好程序员web前端培训分享React学习笔记(三),组件的生命周期 React中组件也有生命周期,也就是说也有很多钩子函数供我们使用, 组件的生命周期,我们会分为四个阶段,初始化.运行中.销毁.错误处 ...

  6. vue如何获取年月日_好程序员web前端教程分享Vue相关面试题

    好程序员web前端教程分享Vue相关面试题,Vue是一套构建用户界面的渐进式框架,具有简单易用.性能好.前后端分离等优势,是web前端工程师工作的好帮手,也是企业选拔人才时考察的重点技能.接下来好程序 ...

  7. 好程序员Web前端教程分享JavaScript开发技巧

    好程序员Web前端教程分享JavaScript开发技巧,相信知道Web前端的小伙伴都熟悉,Javascript的很多扩展的特性是的它变得更加的犀利,同时也给予程序员机会创建更漂亮并且更让用户喜欢的网站 ...

  8. 引入js_好程序员web前端教程分享js中的模块化一

    好程序员web前端教程分享js中的模块化一:我们知道最常见的模块化方案有CommonJS.AMD.CMD.ES6,AMD规范一般用于浏览器,异步的,因为模块加载是异步的,js解释是同步的,所以有时候导 ...

  9. 好程序员web前端教程分享网页设计需要学那些东西?

    好程序员web前端教程分享网页设计需要学那些东西:初次接触或者想要进入网页设计行业的朋友会经常分不清楚web前端与网页设计之间的区别,不知道网页设计要学什么,web前端要学什么,因此感到很迷茫,下面老 ...

最新文章

  1. Tiny4412 Uboot
  2. Qt下使用OpenCV3打开摄像头并把图像显示到QLabel上
  3. 20172324 2017-2018-2《程序设计与数据结构》实验三报告
  4. ahci模式下无法启动Linux,电脑AHCI模式无法开启是怎么回事?
  5. 前端:JS/38/canvas状态的保存和恢复(canvas常用状态大全),canvas画布中图像的变形
  6. input和textarea的区别
  7. 跨境电商独立站模式解析与机会分析?
  8. 2015,鬼王Xun和GGL比赛,带给我们无尽的欢乐
  9. linux 6.8安装 mysql_linux centos6.8 安装 mysql5.7.zip(完整版)
  10. android自定义pickerview,开源项目 好用的PickerView库了
  11. resin 配置java_resin安装与配置
  12. 微信用户昵称特殊符号处理
  13. amd支持服务器内存,AMD专用内存为什么只能在AMD平台使用?与普通内存有什么区别?...
  14. MySQL数据库报错:no database selected
  15. py3_VSCode 配置 Python 环境以及初识 Python 正则表达式
  16. 论证是一门学问 如何让你的观点有说服力-6 规则6 措辞前后一致
  17. IE打不开了,该怎么办?
  18. 内存优化(一)浅谈内存优化
  19. 查看自己电脑应用对应的端口号
  20. 数据集特征提取_特征提取和选择

热门文章

  1. 3.2 选择最可能的句子-深度学习第五课《序列模型》-Stanford吴恩达教授
  2. shell排序-c语言
  3. 【DIY】200403近期在做的项目小结,DIY进展汇报
  4. 基于Proteus的计算器仿真
  5. 基于小波shint/DCT编码压缩解压缩的FPGA实现
  6. Gradle 使用技巧(一)
  7. bzoj2720 [Violet 5]列队春游
  8. 斯坦福大学的机器学习跟深度学习。
  9. Intellij IDEA 提交代码到远程GitHub仓库
  10. jQuery学习笔记(简介,选择器)