第1章:React入门
一、React简介
1.什么是React?
React是一个用于构建用户界面的Javascript库
作用:
- 发送请求获取数据
- 处理数据(过滤、整理格式等)
- 操作DOM呈现页面
2.谁开发的?
Facebook开发,且开源
3.为什么要学?
原生JavaScript的缺点:
- 原生JavaScript操作DOM繁琐、效率低( DOM-API操作UI 比如说一堆的document.getElementById方法获取DOM操作UI)
- 使用JavaScript直接操作DOM,浏览器会进行大量的重绘重排
- 原生JavaScript没有 组件化 编码方案,代码复用率低
4.React的特点
- 采用 组件化 模式、声明式编码,提高开发效率及组件复用率
- 在 React Native 中可以使用React语法进行 移动端开发
- 使用 虚拟DOM +优秀的 Diffing算法 ,尽量减少与真实DOM的交互
二、React的基本使用
1.相关js库
-
React.js:React核心库
-
React-dom.js:提供操作DOM的react拓展库
-
babel.min.js:提供JSX语法的代码转为JS代码的库
jsx语法:用于将ES6之后的语法转换为之前版本的,浏览器可以理解的语法,用于提高网站的可阅读性
2.引入顺序
- 引入React核心库
- 引入React-dom,用于支持 react 操作DOM
- 引入babel,用于将 jsx 转为 js
3.创建虚拟DOM方法
第一种方式:JSX语法( 需要babel转义 )JSX 是 React语法糖
<script type="text/babel">
//1.创建虚拟DOM
const VDOM = <h1>Hello,React</h1>
//2.渲染虚拟DOM到页面
ReactDOM.render(VDOM,document.getElementsById("app"))
</script>
第二种方式:原生JS语法 ( 一般不用 )
<scipt type="text/javascript">
//创建虚拟DOM
const VDOM = React.createElement("h1",{id:"title",class:"titles"},'Hello React')
//渲染虚拟DOM到页面
ReactDOM.render(VDOM,document.getElementById("app"))
</scipt>
4.虚拟DOM
- 虚拟dom本质是Object类型的对象( 一般对象 )
- 虚拟dom比较 轻 ,真实DOM比较 重 ,因为虚拟DOM是React内部在用,无需真实DOM上那么多的属性
- 虚拟DOM最终会被React转化为真实DOM,呈现在页面上
三、JSX
1.JSX介绍
- 全称:JavaScript XML
- react定义的一种类似于XML的JS拓展语法: JS-XML
- 本质是
React.createElement(component,props, ...children)方法的语法糖 - 作用:用来简化创建虚拟DOM
- 写法:
var element = <h1>Hello JSX </h1> - 它不是字符串,也不是HTML/XML标签
- 它最终产生的就是一个 JS对象
- 写法:
- 标签名任意:HTML标签或其他标签
<script type="text/babel">
const VDOM = {
<h2 id="app">
<span>Hello React</span>
</h2>
}
ReactDOM.render(VDOM,document.getElementById("app"))
</script>
2.JSX语法规则
- 定义虚拟DOM时,不要写引号
- 标签中混入JS表达式时要用
{ name } - 使用内联样式需要用双花括号
{{ name }} - 样式的类名要用
className而不是class - 虚拟DOM只可以渲染一个根节点,可以使用
React.Fragment - 标签必须闭合
- 标签首字母:
- 若小写字母开头,则将该标签转换为html中同名元素,若html中无对应的同名元素,则报错
- 若大写字母开头,react就去渲染对应的组件,若组件没有定义,就会报错
四、模块与组件、模块儿化与组件化的理解
1.模块
- 理解:向外提供特定功能的js程序,一般就是一个js文件
- 为什么要拆成模块:随着业务逻辑增加,代码越来越多且复杂
- 作用:复用js,简化js的编写,提高js运行效率
2.组件
- 理解:用来实现局部效果的代码和资源的集合
- 为什么:一个界面的功能更复杂
- 作用:复用编码,简化项目代码,提高运行效率
3.模块化
当应用的js都以模块来编写,这个应用就是一个模块化的应用
4.组件化
当应用时以多组件的方式实现,这个应用就是一个组件化的应用
第2章:React面向组件编程
一、基本理解与使用
1.React开发者工具调试
打包以后就是正常的React图标
没打包时候时不正常规定React图标
2.效果
-
函数式组件
//1.创建函数式组件 function Demo(){ return <h2>我是函数式组件</h2> } //2.渲染组件到页面 ReactDOM.render(<Demo/>,document.getElementById("App")) /* 执行了ReactDOM.render(<Component/>) 之后 1.React解析组件标签,找到组件 <Component/> 2.发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM渲染为真实DOM,渲染到页面中 */ -
类组件
类的基本知识
//创建一个Person的类 class Person{ //构造器方法 constructor(name,age){ //构造器中的this是谁? —— 类的实例对象 this.name = name this.age = age } //一般方法 speak(){ //speak方法放在了哪里? —— 类的原型对象上,给实例用的 //通过Person实例调用speak时,speak中的 this 就是 Person实例 console.log(`我叫${this.name},年龄是${this.age}`) } } //实例化一个对象 const p1 = new Person('tom',18) const p2 = new Person('jerrry',19) console.log(p1) console.log(p2) p1.speak() p2.speak() //speak中的this不一定就是Person实例 p1.speak.call({a:1,b:2})//创建一个Person的类 class Person{ //构造器方法 —— 不是必须的 constructor(name,age){ //构造器中的this是谁? —— 类的实例对象 this.name = name this.age = age } //一般方法 speak(){ //speak方法放在了哪里? —— 类的原型对象上,给实例用的 //通过Person实例调用speak时,speak中的 this 就是 Person实例 console.log(`我叫${this.name},年龄是${this.age}`) } } class Student extends Person{ constructor(name,age,grade){ //super方法调用父类的构造器 super(name,age) this.name = name } //重写从父类继承过来的方法 speak(){ console.log(`我叫${this.name},年龄是${this.age},我还是${this.grade}`) } //study方法放在了类的原型对象上,供实例使用 study(){ console.log('我很努力的学习') } } const s1 = new Student('校长','20','县长儿子') console.log(s1) s1.speak() s1.study()总结:
- 类中的构造器不是必须要写的,要对实例进行一些初始化的操作,如添加指定属性时,才写
- 如果A类继承了B类,且A类中写了构造器,那么A类构造器中的super时必须要调用的
- 类中锁定义的方法,都是放在了类的原型对象上,让实例使用的
创建类式组件
//1.创建类组件 class App extends Component { render() { return ( //render 是放在哪里的? —— 类的原型对象上,供实例对象使用 <div>This is an App</div> ) } } //2.渲染组件到页面 ReactDOM.createRoot(document.getElementById('root')).render(<App />); /* 执行了ReactDom。createRoot之后,发生了什么 1.React解析组件标签,找到了组件 2.发现组件时使用类定义的,随后new出来该类的实例,并通过该实例调用到原型上的render方法 3.将render返回的虚拟DOM转为真实DOM,随后呈现在页面中 */
二、组件三大核心属性:state
1.介绍
- state是组件对象最重要的属性,值是对象(可以包含多个 key-value 的组合)
- 组件被称为 “ 状态机 ”,通过更新组件的 state 来更新对应的页面现实 ( 重新渲染组件 )
【注意】:
- 组件中render方法中的this为实例对象
- 组件自定义的方法中 this 为 undefined,如何解决
- 强制绑定this:通过函数对象的bind方法
- 箭头函数
- 状态数据,不能直接修改或更新
- 组件三大核心属性
2.使用
//1.创建组件
class App extends Component {
constructor(props) {
super(props)
this.state = {
weather:"hot"
}
}
render() {
console.log(this)
return (
<div>This is {this.state.weather} App</div>
)
}
}
//2.渲染组件到页面
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
3.事件绑定
class App extends Component {
constructor(props) {
super(props)
this.state = {
weather:"hot"
}
}
render() {
console.log(this)
function demo() {
this.state.weather="cold"
}
return (
<div onClick={demo}>This is {this.state.weather} App</div>
)
}
}
import React, { Component } from 'react'
class App extends Component {
constructor(props) {
super(props)
this.state = {
weather:"hot"
}
}
render() {
console.log(this)
return (
<div onClick={this.demo}>This is {this.state.weather} App</div>
)
}
// 方法需要放在原型的对象上,供实例使用
// 由于changeWeather是作为onClick的回调,所以不是通过实例调用的,是直接调用
//类中的方法默认开启了局部的严格模式,所以changeWeather中的this是undefined
demo() {
// 通过Weather实例调用changeWeather时
this.setState.weather="cold"
}
}
export default App