React 简介和特点
用于构建用户界面的 JavaScript 库;
声明式编程
- 声明式编程是目前整个大前端开发的模式:Vue、React、Flutter、SwiftUI;
- 它允许我们只需要维护自己的状态,当状态改变时,React可以根据最新的状态去渲染我们的UI界面;
组件化开发
- 组件化开发页面目前前端的流行趋势,我们会将复杂的界面拆分成一个个小的组件;
- 如何合理的进行组件的划分和设计也是后面我会讲到的一个重点;
多平台适配
- 2013年,React发布之初主要是开发Web页面
- 2015年,Facebook推出了ReactNative,用于开发移动端跨平台;(虽然目前Flutter非常火爆,但是还是有很多公司在使用 ReactNative)
- 2017年,Facebook推出ReactVR,用于开发虚拟现实Web应用程序;(VR也会是一个火爆的应用场景)
React由Facebook来更新和维护,它是大量优秀程序员的思想结晶:
- React的流行不仅仅局限于普通开发工程师对它的认可;
- 大量流行的其他框架借鉴React的思想;
Vue.js框架设计之初,有很多的灵感来自Angular和React。
- 包括Vue3很多新的特性,也是借鉴和学习了React;
- 比如React Hooks是开创性的新功能;
- Vue Composition API学习了React Hooks的思想;
Flutter的很多灵感都来自React,来自官网的一段话:(SwiftUI呢)
- 事实上Flutter中的Widget – Element – RenderObject;
- 对应React的就是JSX – 虚拟DOM – 真实DOM;
所以React可以说是前端的先驱者,它总是会引领整个前端的潮流。
组件化中的事件绑定
- 因为在正常的DOM操作中,监听点击,监听函数中的this其实是节点对象(比如说是button对象)
- 这次因为React并不是直接渲染成真实的DOM,我们所编写的button只是一个语法糖,它的本质React的Element对象;
- 那么在这里发生监听的时候,react在执行函数时并没有绑定this,默认情况下就是一个undefined;相当于一个默认调用
<button onClick={this.btn1Click}>按钮1</button>
通过babel转换后成为
React.createElement(
"li",
{click=btn1Click},
"\u5217\u8868\u6570\u636E2"
),
所以在按钮调用的时候 就会变成 btn1Click() 默认调用 在react中默认严格模式 foo(); // 默认绑定 => window => 严格模式下 => undefined
/*
this的四种绑定规则:
1.默认绑定 独立执行 foo()
2.隐式绑定 被一个对象执行 obj.foo() -> obj
3.显式绑定: call/apply/bind foo.call("aaa") -> String("aaa")
4.new绑定: new Foo() -> 创建一个新对象, 并且赋值给this
*/
- 方案一:bind给btnClick显示绑定this
- 方案二:使用 ES6 class fields 语法
- 方案三:事件监听时传入箭头函数(个人推荐)
{/* 1.this绑定方式一: bind绑定 */}
<button onClick={this.btn1Click.bind(this,'222'}>按钮1</button>
{/* 2.this绑定方式二: ES6 class fields */}
constructor() {
super()
this.btn1Click = this.btn2Click.bind(this)
}
<button onClick={this.btn2Click}>按钮2</button>
{/* 3.this绑定方式三: 直接传入一个箭头函数(重要) */}
evnet可以做一些事 比如 阻止点击默认事件
<button onClick={(event) => this.btn3Click(evnet,'222')}>按钮3</button>
组件化中的属性绑定
render() {
const { title, imgURL, href, isActive, objStyle } = this.state
// 需求: isActive: true -> active
// 1.class绑定的写法一: 字符串的拼接
const className = `abc cba ${isActive ? 'active': ''}`
// 2.class绑定的写法二: 将所有的class放到数组中
const classList = ["abc", "cba"]
if (isActive) classList.push("active")
// 3.class绑定的写法三: 第三方库classnames -> npm install classnames
return (
<div>
{ /* 1.基本属性绑定 */ }
<h2 title={title}>我是h2元素</h2>
{/*<img src={imgURL} alt=""/>*/}
<a href={href}>百度一下</a>
{ /* 2.绑定class属性: 最好使用className */ }
<h2 className={className}>哈哈哈哈</h2>
<h2 className={classList.join(" ")}>哈哈哈哈</h2>
{ /* 3.绑定style属性: 绑定对象类型 */ }
<h2 style={{color: "red", fontSize: "30px"}}>呵呵呵呵</h2>
<h2 style={objStyle}>呵呵呵呵</h2>
</div>
)
}
JSX的本质
JSX 其实就是 React.createElement()然后 创建出来一个 ReactElement对象 最终组成了一个JavaScript的对象树 也就是虚拟DOM
这样React 整个流程就会变成 JSX-使用babel-通过React.createElement -形成了虚拟DOM -通过document.createElement() 转换成真实DOM
对标Vue 中解析html过程
Vue中会有大量的template-解析成为AST抽象语法书 -通过render 内部调用了大量的h函数 形成VNode 最后形成一个VnodeTree-真实dom
因为在vue的Template中有很多指令 (v-for v-if)都需要解析。所以底层帮忙做了很多解析的 但是在react 中直接通过Babel来进行转换 所以react会很直观