这是我参与「第四届青训营 」笔记创作活动的的第26天
本文是面向有前端三件套和至少一门高级编程语言基础的同学的自学笔记
介绍
是专门用于生成用户界面的JS库
React和Jquery的区别在于,后者是封装好的一些代码,代码本质上还是对DOM进行操作,而前者在用户和DOM之间加了一层虚拟DOM,通过虚拟DOM映射真实DOM,好处在于React可以将操作DOM的效率提升到最高
搭建环境
React也是JS库,因此需要准备的就是相关.js文件,并以script标签引入
引入示例(注意顺序):
React使用的JS语法在原本JS的语法上有增添,被称为JSX(JS+ XML),babel就是用来将JSX转化为JS的库
增添语法表现为,在JS中可以直接写html代码,简化了对结构的操作
创建虚拟DOM
虚拟DOM就是JS中定义的一个对象,该对象模拟了真实DOM的功能,但又相比前者更轻量,在需要实时更新的情况下运行速度更快,但最终呈现在页面上时,还是需要转化为真实DOM呈现
JSX(实用)
var vdom = (
hello world
)
JS(一般不用)
var vdom = React.createElement(
'h1', null,
React.createElement(
'span', null, 'Hello World'
)
);
这部分JS代码,就是上面JSX通过babel翻译过来的
呈现虚拟DOM
虚拟DOM呈现仍然需要一个真实的DOM,因此在页面中需要一个容器,然后将虚拟DOM渲染到该容器上去
ReactDOM.render(vdom, div)
其中div是通过真实dom获取的页面容器
JSX语法规则
1. 定义虚拟DOM时,不需要对标签字符串加上双引号
2. 在标签内可以使用JS表达式(不能是控制语句),但需要使用{}将其框住
3. 标签中class应写成className
4. 标签中内联样式的格式为{{key1:’value1’,key2...}}
5. 一个虚拟DOM只能有一个根标签
6. 标签必须闭合,因此单标签可以在最后加一个斜杠表示闭合
7. 小写字母开头的标签会被识别成html标签,大写字母开头的标签会被识别为组件
模块和组件
模块
指封装了一定功能的JS文件
组件
指封装了一定有意义内容的页面元素,包含了该页面元素的html,css和js
分为函数式和类式,前者适用于简单组件,后者适用于复杂组件
为什么要用组件?
组件用是JS面向对象思想封装HTML页面元素的手段,通过封装,我们可以给页面元素添加特定的属性和方法
因此,采取(类)组件后,整体的操作逻辑为:
1.定义虚拟DOM
2.使用类组件封装DOM
3.获取真实DOM
4.将组件放入真实DOM中
函数式
指用一个函数定义一个组件,方法将函数的返回值设置为该组件的内容(例如JSX标签)
组件如何被渲染到页面元素中去?
ReactDOM.render(
,
document.getElementsByClassName('test')[0]
)
注意标签名(组件名/函数名)必须以大写字母开头(详见JSX语法规则)
另一种方法也可以实现,但并非以组件的形式
前者是告诉react定义一个组件,react会去调用函数获得内容,而后者是直接调用函数,将返回值给render函数
ReactDOM.render(
demo(),
document.getElementsByClassName('test')[0]
)
类式
定义:
class Mycomponent extends React.Component{
render(){
return(
hello world
)
}
}
渲染到DOM中的方法和函数式相同,定义类时注意需要继承,不需要写构造函数,写一个render函数即可
类式组件三大属性
我们重点学习类式组件,并学习其实例的属性(从component继承)
State
State变量将会储存当前组件的状态信息,一般被定义成一个字典(因为不止一个状态属性)
State和其他普通或者自定义属性不同的点在于,前者有setState等专用的方法
修改state
注意直接对组件类state的修改是无效的,需要借助API
例如
this.setState({judge:!this.state.judge});
案例
State有什么用?state是HTML展示和JS之间的桥梁
我们可以将虚拟DOM定义为和state相关的量,这样就可以通过JS操控state实时改变页面上展示的效果
实现方法1:
// 定义组件
class Mycomponent extends React.Component{
constructor(props){
super(props);
this.state={judge:true};
// 注意点:类内 change 函数被连接到 onclick 上
// 但真正因为点击而调用的时候,不是由类去调用,而是系统去调用
// 因此 this 指针不会指向实例,而是指向 window (或 undefined ),所以要用 bind 将 change 函数的 this 指定为当前实例的 this
this.change=this.change.bind(this);
}
// 定义组件内部的虚拟 DOM
render(){
return(
// 虚拟 DOM 内具体内容和 state 有关
<h1 onClick={this.change}>hello {this.state.judge?'world':'word'}
)
}
// 通过点击改变 state 的值
change(){
// 1. 修改 state 需要使用 API 而非赋值语句**
//2.set 的过程,有写的修改,没写的保持
this.setState({judge:!this.state.judge});
}
}
ReactDOM.render(
,
document.getElementsByClassName('test')[0]
)
React帮助用户完成的事情是,当state发生改变时,会调用一次render,即重构虚拟DOM,实时刷新页面元素
实现方法2(推荐简洁版):
// 定义组件
class Mycomponent extends React.Component{
// 初始化 state
state={judge:true};
// 定义组件内部的虚拟 DOM
render(){
return(
// 虚拟 DOM 内具体内容和 state 有关
<h1 onClick={this.change}>hello {this.state.judge?'world':'word'}
)
}
// 通过点击改变 state 的值
change=()=>{
this.setState({judge:!this.state.judge});
}
}
ReactDOM.render(
,
document.getElementsByClassName('test')[0]
)
开发工具
Microsoft edge扩展react developer tools
可以查看当前页面的react组件