React核心用法查询手册

一、JavaScript基础复习

1. 原生的事件绑定的三种方法

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>Document</title>
	</head>
	<body>
		<button id="btn1">按钮1</button>
		<button id="btn2">按钮2</button>
		<button onclick="demo()">按钮3</button>
  
		<script type="text/javascript" >
			const btn1 = document.getElementById('btn1')
			btn1.addEventListener('click',()=>{
				alert('按钮1被点击了')
			})
   
			const btn2 = document.getElementById('btn2')
			btn2.onclick = ()=>{
				alert('按钮2被点击了')
			}

			function demo(){
				alert('按钮3被点击了')
			}

		</script>
	</body>
</html>

2. 类的基本知识

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>1_类的基本知识</title>
</head>
<body>
	<script type="text/javascript" >
		/* 总结:
      1.类中的构造器不是必须要写的,要对实例进行一些初始化的操作,如添加指定属性时才写。
      2.如果A类继承了B类,且A类中写了构造器,那么A类构造器中的super是必须要调用的。
      3.类中所定义的方法,都放在了类的原型对象上,供实例去使用。*/
		//创建一个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}`);
			}
		}

		//创建一个Student类,继承于Person类
		class Student extends Person {
			constructor(name,age,grade){
				super(name,age)
				this.grade = grade
				this.school = '尚硅谷'
			}
			//重写从父类继承过来的方法
			speak(){
				console.log(`我叫${this.name},我年龄是${this.age},我读的是${this.grade}年级`);
				this.study()
			}
			study(){
				//study方法放在了哪里?——类的原型对象上,供实例使用
				//通过Student实例调用study时,study中的this就是Student实例
				console.log('我很努力的学习');
			}
		}
		
		class Car {
			constructor(name,price){
				this.name = name
				this.price = price
				// this.wheel = 4
			}
			//类中可以直接写赋值语句,如下代码的含义是:给Car的实例对象添加一个属性,名为a,值为1
			a = 1
			wheel = 4
			static demo = 100
		}
		const c1 = new Car('奔驰c63',199)
		console.log(c1);
		console.log(Car.demo);
	</script>
</body>
</html>

3. 箭头函数

引入箭头函数有两个方面的作用:更简短的函数并且不绑定this

x => x * x

上面的箭头函数相当于:

function (x) {
   return x * x;
}

如果参数不是一个,就需要用括号( )括起来

// 两个参数:
(x, y) => x * x + y * y
// 无参数:
() => 3.14
// 可变参数:
(x, y, ...rest) => {
    var i, sum = x + y;
    for (i=0; i<rest.length; i++) {
        sum += rest[i];
    }
    return sum;
}

4. 展开运算符

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>Document</title>
	</head>
	<body>
		<script type="text/javascript" >
			let arr1 = [1,3,5,7,9]
			let arr2 = [2,4,6,8,10]
			console.log(...arr1); //展开一个数组
			let arr3 = [...arr1,...arr2]//连接数组

			//构造字面量对象时使用展开语法
			let person = {name:'tom',age:18}
			let person2 = {...person}
            
			//console.log(...person); //报错,展开运算符不能展开对象
			person.name = 'jerry'
			console.log(person2);
			console.log(person);

			//合并
			let person3 = {...person,name:'jack',address:"地球"}
			console.log(person3);
		</script>
	</body>
</html>

二、JSX语法

1. 简介

  • 全称:JSX的全称是JavaScript XML,是React定义的一种类似于XML的JS扩展语法
  • 本质:是React.createElement(component,pros,…children)方法的语法糖
  • 作用:用来简化创建虚拟DOM 写法:
  • 写法:
var ele = <h1>Hello JSX!</h1>

(注意:它不是字符串, 也不是HTML/XML标签,它最终产生的就是一个JS对象)

2. 如何渲染虚拟DOM(元素)

  • 语法:ReactDOM.render(virtualDOM, containerDOM)
  • 作用:将虚拟DOM元素渲染到页面中的真实容器DOM中显示
  • 参数说明:
    1)参数一: 纯js或jsx创建的虚拟dom对象
    2)参数二: 用来包含虚拟DOM元素的真实dom元素对象(一般是一个div)

3. JSX语法规则

  • 定义虚拟DOM时,不要写引号
  • 标签中混入JS表达式时要用{}
  • 样式的类名指定不要用class,要用className
  • 内联样式,要用style={{key:value}}的形式去写
  • 只有一个根标签
  • 标签必须闭合
  • 标签首字母
    1) 若小写字母开头,则将该标签转为html中同名元素,若html中无该标签对应的同名元素,则报错
    2) 若大写字母开头,react就去渲染对应的组件,若组件没有定义,则报错

4. 实例代码

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>jsx语法规则</title>
	<style>
		.title{
			background-color: orange;
			width: 200px;
		}
	</style>
</head>
<body>
	<!-- 准备好一个“容器” -->
	<div id="test"></div>
	<!-- 引入react核心库 -->
	<script type="text/javascript" src="../js/react.development.js"></script>
	<!-- 引入react-dom,用于支持react操作DOM -->
	<script type="text/javascript" src="../js/react-dom.development.js"></script>
	<!-- 引入babel,用于将jsx转为js -->
	<script type="text/javascript" src="../js/babel.min.js"></script>

	<script type="text/babel" >
		const myId = 'aTgUiGu'
		const myData = 'HeLlo,rEaCt'

		//第一步.创建虚拟DOM
		const VDOM = (
			<div>
				<h2 className="title" id={myId.toLowerCase()}>
					<span style={{color:'white',fontSize:'29px'}}>{myData.toLowerCase()}</span>
				</h2>
				<h2 className="title" id={myId.toUpperCase()}>
					<span style={{color:'white',fontSize:'29px'}}>{myData.toLowerCase()}</span>
				</h2>
				<input type="text"/>
			</div>
		)
		//第二步.渲染虚拟DOM到页面
		ReactDOM.render(VDOM,document.getElementById('test'))
	</script>
</body>
</html>

5. 小练习

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>jsx小练习</title>
</head>
<body>
	<div id="test"></div>
	<script type="text/javascript" src="../js/react.development.js"></script>
	<script type="text/javascript" src="../js/react-dom.development.js"></script>
	<script type="text/javascript" src="../js/babel.min.js"></script>
	<script type="text/babel" >
		//模拟一些数据
		const data = ['Angular','React','Vue']
		//1.创建虚拟DOM
		const VDOM = (
			<div>
				<h1>前端js框架列表</h1>
				<ul>
					{
						data.map((item,index)=>{
							return <li key={index}>{item}</li>
						})
					}
				</ul>
			</div>
		)
		//2.渲染虚拟DOM到页面
		ReactDOM.render(VDOM,document.getElementById('test'))
	</script>
</body>
</html>

三、React面向组件编程

1. 函数式组件

<script type="text/babel">
 //1.创建函数式组件
 function MyComponent(){
  console.log(this); //此处的this是undefined,因为babel编译后开启了严格模式
  return <h2>我是用函数定义的组件(适用于【简单组件】的定义)</h2>
 }
 //2.渲染组件到页面
 ReactDOM.render(<MyComponent/>,document.getElementById('test'))
 /* 
  执行了ReactDOM.render(<MyComponent/>.......之后,发生了什么?
    1.React解析组件标签,找到了MyComponent组件。
    2.发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DOM,随后呈现在页面中。
 */
</script>

2. 类式组件

<script type="text/babel">
 //1.创建函数式组件
 function MyComponent(){
  console.log(this); //此处的this是undefined,因为babel编译后开启了严格模式
  return <h2>我是用函数定义的组件(适用于【简单组件】的定义)</h2>
 }
 //2.渲染组件到页面
 ReactDOM.render(<MyComponent/>,document.getElementById('test'))
 /* 
  执行了ReactDOM.render(<MyComponent/>.......之后,发生了什么?
    1.React解析组件标签,找到了MyComponent组件。
    2.发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DOM,随后呈现在页面中。
 */
</script>

render是放在哪里的? --MyComponent的原型对象上,供实例使用
render中的this是谁? --MyComponent的实例对象 <=> MyComponent组件实例对象
复杂组件和简单组件区别:有state的就是复杂组件,没有的则是简单组件
注意

  1. 组件名必须首字母大写
  2. 虚拟DOM元素只能有一个根元素
  3. 虚拟DOM元素必须有结束标签

渲染类组件标签的基本流程

  1. React内部会创建组件实例对象
  2. 调用render()得到虚拟DOM, 并解析为真实DOM
  3. 插入到指定的页面元素内部

执行了ReactDOM.render(…之后,发生了什么?
React解析组件标签,找到了MyComponent组件
发现组件是使用类定义的,随后new出来该类的实例,并通过该实例调用到原型上的render方法
将render返回的虚拟DOM转为真实DOM,随后呈现在页面中

3. 组件实例的三大核心属性

① state

理解
state是组件对象最重要的属性,值是对象(可以包含多个key-value的组合)
组件被称为‘状态机’,通过更新组件的state来更新对应的页面显示(重新渲染)

注意
组件中render方法中的this为组件实例对象
组件自定义的方法中this为undefined,如何解决?
a) 强制绑定this: 通过函数对象的bind()
b) 箭头函数
状态数据,不能直接修改或更新,需要使用setState

state详细使用方式

//1.创建组件
		class Weather extends React.Component{
			constructor(props){
				console.log('constructor');
				super(props)
				this.state = {isHot:false, wind:'微风'}
				//解决下面changeWeather中this指向问题
				this.changeWeather = this.changeWeather.bind(this)
			}
			//render调用几次? — 1+n次 1是初始化的那次 n是状态更新的次数
			render(){
				console.log('render');
				//读取状态
				const {isHot,wind} = this.state
				//由于changeWeather是作为onClick的回调,所以不是通过实例调用的,是直接调用
				return <h1 onClick={this.changeWeather}>今天天气很{isHot ? '炎热' : '凉爽'}{wind}</h1>
			}
			changeWeather(){
				console.log('changeWeather');
				//获取原来的isHot值
				const isHot = this.state.isHot
				//严重注意:状态必须通过setState进行更新,且更新是一种合并,不是替换。
				this.setState({isHot:!isHot})
				console.log(this);
				//严重注意:状态(state)不可直接更改,下面这行就是直接更改!!!
				//this.state.isHot = !isHot //这是错误的写法
			}
		}
		ReactDOM.render(<Weather/>,document.getElementById('test'))

② props

理解:
每个组件对象都会有props(properties的简写)属性
组件标签的所有属性都保存在props中作用

作用:
通过标签属性从组件外向组件内传递变化的数据
注意: 组件内部不要修改props数据

编码操作:
1.内部读取某个属性值

this.props.name

2.对props中的属性值进行类型限制和必要性限制
使用prop-types库进限制(需要引入prop-types库)

Person.propTypes = {
  name: PropTypes.string.isRequired,
  age: PropTypes.number. 
}

3.扩展属性: 将对象的所有属性通过props传递

<Person {...person}/>

4.默认属性值

Person.defaultProps = {
  age: 18,
  sex:'男'
}

5.组件类的构造函数

constructor(props){
  super(props)
  console.log(props)//打印所有属性
}

props基本使用

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>props基本使用</title>
</head>
<body>
	<!-- 准备好“容器” -->
	<div id="test1"></div>
	<div id="test2"></div>
	<div id="test3"></div>
	<script type="text/javascript" src="../js/react.development.js"></script>
	<script type="text/javascript" src="../js/react-dom.development.js"></script>
	<script type="text/javascript" src="../js/babel.min.js"></script>
	<script type="text/babel">
		//创建组件
		class Person extends React.Component{
			render(){
				// console.log(this);
				const {name,age,sex} = this.props
				return (
					<ul>
						<li>姓名:{name}</li>
						<li>性别:{sex}</li>
						<li>年龄:{age+1}</li>
					</ul>
				)
			}
		}      
		//渲染组件到页面,和state的区别是我们在组件外面渲染
        //如果想使用Number类型参数,则需要写成{arg}形式
		ReactDOM.render(<Person name="jerry" age={19}  sex="男"/>,document.getElementById('test1'))
		ReactDOM.render(<Person name="tom" age="18" sex="女"/>,document.getElementById('test2'))
		
		//批量传参渲染(通过展开运算符)
		const p = {name:'老刘',age:18,sex:'女'}
		ReactDOM.render(<Person {...p}/>,document.getElementById('test3'))
	</script>
</body>
</html>

限制props参数

第一步:
<!-- 引入prop-types,用于对组件标签属性进行限制 -->
<script type="text/javascript" src="../js/prop-types.js"></script>
第二步:
//对标签属性进行类型、必要性的限制
	Person.propTypes = {
		name:PropTypes.string.isRequired, //限制name必传,且为字符串
		sex:PropTypes.string,//限制sex为字符串
		age:PropTypes.number,//限制age为数值
		speak:PropTypes.func,//限制speak为函数
	}
	//指定默认标签属性值
	Person.defaultProps = {
		sex:'男',//sex默认值为男
		age:18 //age默认值为18
	}

③ refs

理解
组件内的标签可以定义ref属性来标识自己
ref相当于id,生成的键值对中,key为ref=的值,value为当前语句的整个节点

编码
1.字符串形式的ref

<input ref="input1"/>

2.回调形式的ref

<input ref={(c)=>{this.input1 = c}}

3.createRef创建ref容器·

myRef = React.createRef() 
<input ref={this.myRef}/>

使用方式

//创建组件
		class Demo extends React.Component{
			/* React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点,该容器是“专人专用”的*/
        //创建ref容器
			myRef = React.createRef()
			myRef2 = React.createRef()
			//展示左侧输入框的数据
			showData = ()=>{
				alert(this.myRef.current.value);
			}
			//展示右侧输入框的数据
			showData2 = ()=>{
				alert(this.myRef2.current.value);
			}
			render(){
				return(
					<div>
						<input ref={this.myRef} type="text" placeholder="点击按钮提示数据"/>&nbsp;
						<button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
						<input onBlur={this.showData2} ref={this.myRef2} type="text" placeholder="失去焦点提示数据"/>&nbsp;
					</div>
				)
			}
		}
		//渲染组件到页面
		ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))

4. 事件处理

  1. 通过onXxx属性指定事件处理函数(注意大小写)
    1. React使用的是自定义(合成)事件, 而不是使用的原生DOM事件 — 为了更好的兼容性
    2. React中的事件是通过事件委托方式处理的(委托给组件最外层的元素) — 为了更加的高效
  2. 通过event.target得到发生事件的DOM元素对象 — 不要过度使用ref
    使用方式:
//创建组件
		class Demo extends React.Component{
			//创建ref容器
			myRef = React.createRef()
			myRef2 = React.createRef()

			//展示左侧输入框的数据
			showData = (event)=>{
				console.log(event.target);
				alert(this.myRef.current.value);
			}

			//展示右侧输入框的数据
			showData2 = (event)=>{
				alert(event.target.value);
			}

			render(){
				return(
					<div>
						<input ref={this.myRef} type="text" placeholder="点击按钮提示数据"/>&nbsp;
						<button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
						<input onBlur={this.showData2} type="text" placeholder="失去焦点提示数据"/>&nbsp;
					</div>
				)
			}
		}
		//渲染组件到页面
		ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))

5. 收集表单数据

1、非受控组件

class Login extends React.Component{
			handleSubmit = (event)=>{
				event.preventDefault() //阻止表单提交(因为表单提交默认会页面跳转)
				const {username,password} = this
				alert(`用户名:${username.value},密码:${password.value}`)
			}
			render(){
				return(
                    //onsubmit表单提交操作绑定handleSubmit回调方法
					<form onSubmit={this.handleSubmit}>
						用户名:<input ref={c => this.username = c} type="text" name="username"/>
						密码:<input ref={c => this.password = c} type="password" name="password"/>
						<button>登录</button>
					</form>
				)
			}
		}
		//渲染组件
		ReactDOM.render(<Login/>,document.getElementById('test'))

2、受控组件
什么是受控组件:由组件控制的,将状态保存在组件中相当于VUE的双向绑定

class Login extends React.Component{
			//初始化状态
			state = {
				username:'', //用户名
				password:'' //密码
			}

			//保存用户名到状态中
			saveUsername = (event)=>{
				this.setState({username:event.target.value})
			}

			//保存密码到状态中
			savePassword = (event)=>{
				this.setState({password:event.target.value})
			}

			//表单提交的回调
			handleSubmit = (event)=>{
				event.preventDefault() //阻止表单提交
				const {username,password} = this.state
				alert(`你输入的用户名是:${username},你输入的密码是:${password}`)
			}

			render(){
				return(
					<form onSubmit={this.handleSubmit}>
						用户名:<input onChange={this.saveUsername} type="text" name="username"/>
						密码:<input onChange={this.savePassword} type="password" name="password"/>
						<button>登录</button>
					</form>
				)
			}
		}
		//渲染组件
		ReactDOM.render(<Login/>,document.getElementById('test'))

四、组件的生命周期

理解

  1. 组件从创建到死亡它会经历一些特定的阶段
  2. React组件中包含一系列勾子函数(生命周期回调函数), 会在特定的时刻调用
  3. 我们在定义组件时,会在特定的生命周期回调函数中,做特定的工作
    在这里插入图片描述

1. 生命周期的三个阶段

step1. 初始化阶段

由ReactDOM.render()触发 - 初次渲染
1. constructor()
2. getDerivedStateFromProps
3. render()
4. componentDidMount()

step2. 更新阶段

由组件内部this.setSate()或父组件重新render触发

  1. getDerivedStateFromProps
  2. shouldComponentUpdate()
  3. render()
  4. getSnapshotBeforeUpdate
  5. componentDidUpdate()

step3. 卸载组件

由ReactDOM.unmountComponentAtNode()触发

  1. componentWillUnmount()

2. 重要的勾子

1. render:初始化渲染或更新渲染调用
2. componentDidMount:开启监听, 发送ajax请求
3. componentWillUnmount:做一些收尾工作, 如: 清理定时器

五、React应用(基于React脚手架)

1. 使用create-react-app创建react应用

react脚手架

  1. 脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目,包含了所有需要的配置(语法检查、jsx编译、devServer…);下载好了所有相关的依赖;可以直接运行一个简单效果
  2. react提供了一个用于创建react项目的脚手架库: create-react-app
  3. 项目的整体技术架构为: react + webpack + es6 + eslint
  4. 使用脚手架开发的项目的特点: 模块化, 组件化, 工程化

创建项目并启动

第一步:全局安装:npm i -g create-react-app
第二步:切换到想创项目的目录,使用命令:create-react-app hello-react
第三步:进入项目文件夹:cd hello-react
第四步:启动项目:npm start

react脚手架项目结构

public ---- 静态资源文件夹
        favicon.icon ------ 网站页签图标
        index.html -------- 主页面
        logo192.png ------- logo图
        manifest.json ----- 应用加载的配置文件
        robots.txt -------- 爬虫协议文件
src ---- 源码文件夹
        App.css -------- App组件的样式
        App.js --------- App组件
        App.test.js ---- 用于给App做测试
        index.css ------ 样式
        index.js ------- 入口文件
        logo.svg ------- logo图
        reportWebVitals.js --- 页面性能分析文件(需要web-vitals库的支持)
        setupTests.js ---- 组件单元测试的文件(需要jest-dom库的支持)

功能界面的组件化编码流程(通用)
第一步:拆分组件: 拆分界面,抽取组件
第二步:实现静态组件: 使用组件实现静态页面效果
第三步:实现动态组件

  1. 动态显示初始化数据(数据类型 + 数据名称 + 保存在哪个组件)
  2. 交互(从绑定事件监听开始)

React ajax
理解
3. React本身只关注于界面, 并不包含发送ajax请求的代码
4. 前端应用需要通过ajax请求与后台进行交互(json数据)
5. react应用中需要集成第三方ajax库(或自己封装)

常用的ajax请求库
6. jQuery: 比较重, 如果需要另外引入不建议使用
7. axios: 轻量级, 建议使用

  1. 封装XmlHttpRequest对象的ajax
  2. promise风格
  3. 可以用在浏览器端和node服务器端
  1. axios使用
    相关API
  2. GET请求
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response.data);
  })
  .catch(function (error) {
    console.log(error);
  });
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
  1. POST请求
axios.post('/user', {
  firstName: 'Fred',
  lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});

六、消息订阅-发布机制

工具库: PubSubJS
下载:npm install pubsub-js --save
使用:

  1. import PubSub from ‘pubsub-js’ //引入
  2. PubSub.subscribe(‘delete’, function(data){ }); //订阅
  3. PubSub.publish(‘delete’, data) //发布消息
  1. Fetch
    特点
  2. fetch: 原生函数,不再使用XmlHttpRequest对象提交ajax请求
  3. 老版本浏览器可能不支持
    相关API
  4. GET请求
fetch(url).then(function(response) {
    return response.json()
  }).then(function(data) {
    console.log(data)
  }).catch(function(e) {
    console.log(e)
  });
  1. POST请求
  fetch(url, {
    method: "POST",
    body: JSON.stringify(data),
  }).then(function(data) {
    console.log(data)
  }).catch(function(e) {
    console.log(e)
  })

七、React路由

SPA

  1. 单页Web应用(single page web application,SPA)
  2. 整个应用只有一个完整的页面
  3. 点击页面中的链接不会刷新页面,只会做页面的局部更新
  4. 数据都需要通过ajax请求获取, 并在前端异步展现

路由

  1. 什么是路由?
  2. 一个路由就是一个映射关系(key:value)
  3. key为路径, value可能是function或component
  4. 路由分类
  5. 后端路由:
  1. 理解: value是function, 用来处理客户端提交的请求
  2. 注册路由: router.get(path, function(req, res))
  3. 工作过程:当node接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据
  1. 前端路由:
  1. 浏览器端路由,value是component,用于展示页面内容
  2. 注册路由:
  3. 工作过程:当浏览器的path变为/test时, 当前路由组件就会变为Test组件

react-router-dom

  1. react的一个插件库
  2. 专门用来实现一个SPA应用
  3. 基于react的项目基本都会用到此库

react-router-dom相关API
内置组件:


其它: history对象 match对象 withRouter函数
  1. 基本路由使用
  2. 嵌套路由使用
  3. 向路由组件传递参数数据
  4. 多种路由跳转方式

剩下的还没CV完,歇会再抄

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值