React学习笔记

React全家桶:React基础、React-Router路由、PubSub消息管理、Redux集中式状态管理、Ant-Design一个UI组件库。

一、React入门

1、React是什么?

React是用于构建用户界面的JavaScript库。操作DOM呈现页面。是一个将数据渲染成HTML视图的开源JavaScript库。

2、React由Facebook开发开源的

3、为什么学React

原生JavaScript操作DOM繁琐、效率低(DOM-API操作UI)。使用JavaScript直接操作DOM,浏览器会进行大量的重绘重排。原生JavaScript没有组件化编码方法,代码复用率低。

4、React的特点

1、采用组件化模式,声明式编码,提高开发效率及组件复用率。

2、在React Native中可以使用React语法进行移动端开发。

3、使用虚拟DOM+优秀的Diffing算法,尽量减少与真实DOM的交互。

5、React为什么高效

使用虚拟DOM,不总是直接操作页面真实DOM,DOM Diffing算法,最小化页面重绘

6、学习React之前要掌握的JavaScript基础

判断this的指向、class(类)、ES6语法规范、npm包管理器、原型、原型链、数组常用方法、模块化

7、React的基本使用

(1)React的相关js库

1、react.js:React核心库

2、react-dom.js:提供操作DOM的react扩展库

3、babel.min.js:解析jsx语法代码转化为js代码的库

(2)创建虚拟DOM的两种方法

1、纯js方式(一般不用)

2、jsx方式

(3)虚拟DOM和真实DOM

1、React提供了一些API来创建一种“特别”的一般js对象

/* 创建一个简单的虚拟DOM对象 */
const VDOM = React.createElement('xx',{id:'xx'},'xx')

2、虚拟DOM对象最终都会被React转换为真实的DOM

3、编程时只需要操作react的虚拟DOM的相关数据,react会转换为真实DOM变化而更新姐面

4、虚拟DOM本质就是Object类型的对象。虚拟DOM比较“轻”(属性少),真实DOM比较“重”(属性多)。虚拟DOM是React内部在用,无需真实DOM上那么多的属性。

5、虚拟DOM会被React转换成真实DOM,呈现在页面上。

(4)React JSX

XML:早期用于存储和传输。

全称:JavaScript XML

  1. react定义的一种类似于XMLJS扩展语法: JS + XML本质是React.createElement(componentprops, ...children)方法的语法糖
  2. 作用: 用来简化创建虚拟DOM
    1. 写法:var ele = <h1>Hello JSX!</h1>
    2. 注意1:它不是字符串, 也不是HTML/XML标签
    3. 注意2:它最终产生的就是一个JS对象
  3. 标签名任意: HTML标签或其它标签
  4. 标签属性任意: HTML标签属性或其它
  5. 基本语法规则
    1. 遇到 <开头的代码, 以标签的语法解析: html同名标签转换为html同名元素, 其它标签需要特别解析
    2. 遇到以 { 开头的代码,以JS语法解析: 标签中的js表达式必须用{ }包含
  6. babel.js的作用
    1. 浏览器不能直接解析JSX代码, 需要babel转译为纯JS的代码才能运行
    2. 只要用了JSX,都要加上type="text/babel", 声明需要babel来处理

jsx语法规则:

        1、定义虚拟DOM,不要写引号。

        2、标签中混入js表达式时,用{}包裹。

        3、标签中有多个属性时,用空格隔开。

        4、标签中有多个子元素时,用逗号隔开。

        5、jsx语法编译成js代码时,会自动调用React.createElement()方法。

        6、样式的类名指定时,用className属性,而不是class。

        7、根标签只能有一个,不能有多个。

        8、内联样式要用style={{key:value}}包裹。

        9、标签必须闭合。

        10、标签首字母:

            (1)小写字母开头,则将该标签转为HTML中的同名标签,若HTML中没有同名标签,则会报错。

            (2)大写字母开头,React就去渲染对应的组件,若没有定义该组件,则会报错。

(5)渲染虚拟DOM(元素)

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

8、模块与组件、模块化与组件化的理解

(1)模块
  1. 理解:向外提供特定功能的js程序, 一般就是一个js文件
  2. 为什么要拆成模块:随着业务逻辑增加,代码越来越多且复杂。
  3. 作用:复用js, 简化js的编写, 提高js运行效率
(2)组件
  1. 理解:用来实现局部功能效果的代码和资源的集合(html/css/js/image等等)
  2. 为什么要用组件: 一个界面的功能更复杂
  3. 作用:复用编码, 简化项目编码, 提高运行效率
(3)模块化

当应用的js都以模块来编写的,这个应用就是一个模块的应用

(4)组件化

当应用是以多组件的方式实现, 这个应用就是一个组件化的应用

二、React面向组件编程

1、组件

(1)函数式组件

函数式组件:使用函数编写组件。

类式组件:使用类编写组件。

类的基础知识回顾:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>1、类的基础知识复习</title>
</head>
<body>
    <script type="text/javascript">
        //定义一个Person类
        class Person {
            //构造器函数
            constructor(name, age) {
                this.name = name
                this.age = age
            }
            //一般方法
            sayHello() {
                //sayHello方法放在了类的原型对象上,所以可以直接通过实例对象调用
                console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
            }
        }

        //创建一个student类,继承Person类
        class Student extends Person {
            //构造器函数
            constructor(name, age, grade) {
                super(name, age)
                this.grade = grade
            }
            //重写父类的sayHello方法
            sayHello() {
                console.log(`Hello, my name is ${this.name} and I am ${this.age} years old, I am in grade ${this.grade}.`);
            }
        }

        //实例化Student类
        const student1 = new Student('Jerry', 18, 3);
        console.log(student1); //输出Jerry
        student1.sayHello(); //输出Hello, my name is Jerry and I am 18 years old, I am in grade 3.
        //实例化Person类
        const person1 = new Person('Tom',20);
        console.log(person1); //输出Tom
        person1.sayHello(); //输出Hello, my name is Tom and I am 20 years old.
    </script>
</body>
</html>
 (2)类式组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>类式组件</title>

    <!-- 引入React -->
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

    <!-- 引入Babel -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
    
</head>
<body>
    <!-- 定义一个div作为渲染的目标 -->
    <div id="root"></div>
    <script type="text/babel">
        // 定义一个类式组件
        class Hello extends React.Component {
            render() {
                return <h1>Hello, {this.props.name}!</h1>;
            }
        }

        // 渲染组件
        ReactDOM.render(
            <Hello name="World" />,
            document.getElementById('root')
        );
    </script>
</body>
</html>

 复杂组件与简单组件的区分:

有状态(state)的是复杂组件,没有状态(state)的是简单组件

 (3)状态state

组件实例的三大属性之一。

  1. state是组件对象最重要的属性, 值是对象(可以包含多个key-value的组合)
  2. 组件被称为"状态机", 通过更新组件的state来更新对应的页面显示(重新渲染组件)
  1. 组件中render方法中的this为组件实例对象
  2. 组件自定义的方法中thisundefined,如何解决?
    1. 强制绑定this: 通过函数对象的bind()
    2. 箭头函数
  3. 状态数据,不能直接修改或更新
	<script type="text/babel">
		//1.创建组件
		class Weather extends React.Component{
			//初始化状态
			state = {isHot:false,wind:'微风'}

			render(){
				const {isHot,wind} = this.state
				return <h1 onClick={this.changeWeather}>今天天气很{isHot ? '炎热' : '凉爽'},{wind}</h1>
			}

			//自定义方法————要用赋值语句的形式+箭头函数
			changeWeather = ()=>{
				const isHot = this.state.isHot
				this.setState({isHot:!isHot})
			}
		}
		//2.渲染组件到页面
		ReactDOM.render(<Weather/>,document.getElementById('test'))

	<script type="text/babel">
		//1.创建组件
		class Weather extends React.Component{
			
			//构造器调用几次? ———— 1次
			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
				return <h1 onClick={this.changeWeather}>今天天气很{isHot ? '炎热' : '凉爽'},{wind}</h1>
			}

			//changeWeather调用几次? ———— 点几次调几次
			changeWeather(){
				//changeWeather放在哪里? ———— Weather的原型对象上,供实例使用
				//由于changeWeather是作为onClick的回调,所以不是通过实例调用的,是直接调用
				//类中的方法默认开启了局部的严格模式,所以changeWeather中的this为undefined
				
				console.log('changeWeather');
				//获取原来的isHot值
				const isHot = this.state.isHot
				//严重注意:状态必须通过setState进行更新,且更新是一种合并,不是替换。
				this.setState({isHot:!isHot})
				console.log(this);

				//严重注意:状态(state)不可直接更改,下面这行就是直接更改!!!
				//this.state.isHot = !isHot //这是错误的写法
			}
		}
		//2.渲染组件到页面
		ReactDOM.render(<Weather/>,document.getElementById('test'))
				
	</script>
(4)props:传值

理解

  1. 每个组件对象都会有props(properties的简写)属性
  2. 组件标签的所有属性都保存在props

作用

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

编码操作

        1.内部读取某个属性值

        2.对props中的属性值进行类型限制和必要性限制

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

        4.默认属性值

        5.组件类的构造函数

什么是props

     props 用于组件的传值,他的工作就是为了接受外面传过来的数据,是一个配置项,与data、el、ref 是一个级别的。

props的使用:

        (1)静态props
静态即传入的值不变化,直接在父组件中定义,子组件中使用。
        (2)动态props
动态即传入的值会变化,父组件中要动态地绑定父组件的数据。
        (3)props验证
验证传入的props参数的数据规格,如果不符合数据规格则发出警告,注意这个数据类型包含所有的数据类型,如基本类型和引用类型;还可以在验证中加入自定义验证函数,当返回false时则发出警告。

	<script type="text/babel">
		//创建组件
		class Person extends React.Component{
			render(){
				// console.log(this);
				const {name,age,sex} = this.props
				//props是只读的
				//this.props.name = 'jack' //此行代码会报错,因为props是只读的
				return (
					<ul>
						<li>姓名:{name}</li>
						<li>性别:{sex}</li>
						<li>年龄:{age+1}</li>
					</ul>
				)
			}
		}
		//对标签属性进行类型、必要性的限制
		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
		}
		//渲染组件到页面
		ReactDOM.render(<Person name={100} speak={speak}/>,document.getElementById('test1'))
		ReactDOM.render(<Person name="tom" age={18} sex="女"/>,document.getElementById('test2'))

		const p = {name:'老刘',age:18,sex:'女'}
		// console.log('@',...p);
		// ReactDOM.render(<Person name={p.name} age={p.age} sex={p.sex}/>,document.getElementById('test3'))
		ReactDOM.render(<Person {...p}/>,document.getElementById('test3'))

		function speak(){
			console.log('我说话了');
		}
	</script>
(5)refs与事件处理

对refs的理解:

        组件中的标签可以定义refs属性来标识自己

refs属性编码:

字符串形式的ref

<input ref="input1" />

 回调形式的ref

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

createRef创建ref容器

myRef = React.createRef()
<input ref={this.myRef} />
(6)事件处理: 

事件处理:

通过onXxx属性指定事件处理函数(区分大小写)

        React使用的是自定义(合成)事件,而不是原生DOM事件

        React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)

通过event.target得到发生事件的DOM元素对象

收集表单数据

包含表单的组件分类:受控组件和非受控组件

组件的生命周期

对生命周期的理解:

1、组件从创建到死亡的一些特定的阶段

2、React组件中包含一系列勾子函数(生命周期回调函数),会在特定的时刻回调

3、定义组件时,在特定的生命周期回调函数中,做特定的工作

/* 重要的勾子 */

render                //初始化渲染或更新渲染调用
componetDidMount      //开启监听,发送ajax请求
componentWillUnmount  //完成收尾工作,如:清空定时器

React脚手架项目结构:

public ---- 静态资源文件夹
		favicon.icon ------ 网站页签图标
		index.html -------- 主页面
		logo192.png ------- logo图
		logo512.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库的支持)

React ajax

理解:

        React本身只关注界面,并不包含发送ajax请求的代码

        前端应用需要通过ajax请求与后台进行交互(json数据)

        React应用中需要集成第三方ajax库(自己封装)

常用的ajax请求库

1、jQuery:比较重

2、axios:轻量级

        (1)封装XmlHttpRequest对象的ajax

        (2)promise风格

        (3)可以用在浏览器端和node服务器端

React路由

理解:

一、对SPA的理解:

        1、单页Web应用(single page web application,SPA)

        2、整个应用只有一个完整的页面

        3、点击页面中的链接,不会刷新页面,只会做页面的局部更新

        4、数据需要通过ajax请求获取,并在前端异步展现

二、对路由的理解:

1、什么是路由?

        (1)一个路由就是一个映射关系(key:value)

        (2)key为路径,value可能是函数(funcation)或者组件(component)

2、路由的分类:

        (1)后端路由

                <1>理解:value是funcation,用来处理客户端提出的请求

                <2>注册路由:router.target(path,funcation(req,res))

                <3>工作过程:当node收到一个请求时,根据请求路径找到匹配的路由,调用路

                       由中的函数处理请求,返回响应数据

        (2)前端路由

                <1>浏览器端路由,value是component,用于展示页面内容

                <2>注册路由:<Route path="/test" component={Test}> 

                <3>工作过程:当浏览器的path变为/test时,当前路由组件就会变成Test组件

react-router-dom

对react-router-dom的理解:

        1、react的一个插件库

        2、实现SPA应用

        3、基于React的项目都会用到这个库

react-router-dom相关API

/* 内置插件 */
<BrowserRouter>
<HashRouter>
<Route>
<Redirect>
<Link>
<NavLink>
<Switch>

1、history对象

2、match对象

3、withRouter函数

基本路由使用:

准备工作:

1、下载react-router-dom:

 npm install --save react-router-dom

2、引入bootstrap.css:

2.<link rel="stylesheet" href="/css/bootstrap.css">

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值