react学习笔记

96 阅读3分钟

一、react 介绍

1.1react的特点

  1. 采用组件化模式、声明式编码提高开发效率及组件复用率。
  2. 在React Native中可以使用React语法进行移动端开发。
  3. 使用虚拟DOM+优秀的Diffing算法,尽量减少与真实DOM的交互。

1.2、学习react之前你要掌握的js知识

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

1.3、官网

介绍描述

  • 用于动态构建用户界面的JavaScript库(只关注于视图)
  • 由Facebook开源

React的特点

  • 声明式编码
  • 组件化编码
  • React Native编写原生应用
  • 高效(优秀的Diffing 算法)

二、react 的基本使用

2.1虚拟dom的创建

  • 纯jsS方式(一般不用)
  • JSx方式

1.使用jsx创建虚拟dom

< ! DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>he1lo_react</title>
</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" >/*此处一定要写babel */
        //1.创建虚拟DOM
        const VDOM = <h1>Hello,React</h1>/*此处一定不要写引号,因为不是字符串*/
        //2.渲染虚拟DOM到页面
        ReactDom.render(VDOM,document.getElementId('test'))
    </script>
</body>
</html>

2.使用js 创建虚拟dom

< ! DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>he1lo_react</title>
</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>
   
    <script type="text/javascript">/*此处一定要写javascript*/
        //1.创建虚拟DOM
        const VDOM = React.createElement('h1' ,{id: 'title ' } , ' Hello,React ' )
        //2.渲染虚拟DOM到页面
        ReactDom.render(VDOM,document.getElementId('test'))
        console.log()
        console.1og("虚拟DOM " , VDOM);
        console.log('真实DON" ,TDOM);
        // debugger;
        //console.log(typeof VDOM);
        //console.log(VDOM instanceof 0bject);
        /*
        关于虚拟DOM:
        1.本质是0bject类型的对象(一般对象)
        2.虚拟DOM比较"轻”,真实DOM比较重”,因为虚拟DOM是React内部在用,无需真实DOM上那么多的属性。
        3、虚拟DOM最终会被React转化为真实DOM,呈现在页面上。
        */
    </script>
</body>
</html>

2.2.相关js库

  • react.js: React核心库。
  • react-dom.js:提供操作DOM的react扩展库。
  • babel.min.js:解析JSx语法代码转为S代码的库。

2.3、jsx语法规则

< ! DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>he1lo_react</title>
    <style>
       .title{
         background-color:yellow
        }
    </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'
    
    
        //1.创建虚拟DOM
        const VDOM = (
         <h2 className="title" id={myId.toLowerCase()}>
          <span>{myData.toLowerCase()}</span>
         </h2>
        )
        //2.渲染虚拟DOM到页面
        ReactDom.render(VDOM,document.getElementId('test'))
        
        /*
    jsx语法规则:
    1.定义虚拟DOM时,不要写引号。
    2.标签中混入S表达式时要用{}
    3.样式的类名指定不要用class,要用className
    4.style内联:style={{color:'white'}}
    5、只有一个根标签
    6、标签必须闭合 <input type='text'
    7、标签首字母:
     (1)若小写字母开头,则将改标签转为html中同名元素,若html中无该标签对应的同名元素,则报错。
      (2)若大写字母开头,react就去渲染对应的组件,若组件没有定义,则报错。

*/

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

2.4、jsx小练习

< ! DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>he1lo_react</title>
    <style>
       .title{
         background-color:yellow
        }
    </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 ">
    /*
    一定注意区分:【js语句(代码)】与【js表达式】
    1.表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方
    下面这些都是表达式:
    (1). a
    (2). a+b
    (3). demo(1)
    (4). arr.map()
    2.语句(代码):
    下面这些都是语句(代码):
     (1).if(){}
     (2).for(){}
     (3).switch(){case:xxxx}
 
    */
    //模拟一些数据
    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.getElementId('test'))
       

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

2.5、组件与模块

2.5.1.模块

  1. 理解:向外提供特定功能的js程序,一般就是一个js文件
  2. 为什么要拆成模块:随着业务逻辑增加,代码越来越多且复杂。
  3. 作用:复用js,简化js的编写,提高js运行效率

2.5.2.组件

  1. 理解:用来实现局部功能效果的代码和资源的集合(html/css/js/image等等)
  2. 为什么:一个界面的功能更复杂
  3. 作用:复用编码,简化项目编码,提高运行效率

2.5.3.模块化

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

2.5.4.组件化

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

三、react 面向组件化开发

3.1、开发工具的安装

3.2、react中定义组件

1、函数式组件:函数名就是组件名,没有自己的this

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>1_函数式组件</title>
</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">
            //1.创建函数式组件
            function MyComponent(){
		console.log(this); //此处的this是undefined,因为babel编译后开启了严格模式,禁止this指向window
		return <h2>我是用函数定义的组件(适用于【简单组件】的定义)</h2>
            }
            //2.渲染组件到页面
            ReactDOM.render(<MyComponent/>,document.getElementById('test'))
            /* 
            执行了ReactDOM.render(<MyComponent/>.......之后,发生了什么?
            1.React解析组件标签,找到了MyComponent组件。
            2.发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DOM,随后呈现在页面中。
		*/
	</script>
</body>
</html>

2、类式组件:类名就是组件名:有this

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>2_类式组件</title>
</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">
	//1.创建类式组件
	class MyComponent extends React.Component {
            render(){//render必须写,必须有返回值return
            //render是放在哪里的?—— MyComponent的原型对象上,供实例使用。
            //render中的this是谁?—— MyComponent的实例对象 <=> MyComponent组件实例对象。
            console.log('render中的this:',this);
            return <h2>我是用类定义的组件(适用于【复杂组件】的定义)</h2>
	}
}
	//2.渲染组件到页面
		ReactDOM.render(<MyComponent/>,document.getElementById('test'))
	/* 
	执行了ReactDOM.render(<MyComponent/>.......之后,发生了什么?
	1.React解析组件标签,找到了MyComponent组件。
	2.发现组件是使用类定义的,随后new出来该类的实例,并通过该实例调用到原型上的render方法。
	3.将render返回的虚拟DOM转为真实DOM,随后呈现在页面中。
        */
	</script>
</body>
</html>

3.3、类的基本知识

<!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.4、state的理解

state:组件实例的三大核心属性之一

image.png

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

强烈注意

  1. 组件中render方法中的this为组件实例对象
  2. 组件自定义的方法中 this为undefined,如何解决? a.强制绑定this:通过函数对象的 bind()' b.箭头函数 3.态数据,不能直接修改或更新

3.5、初始化state,类方法中的this,react中的事件绑定,解决类中的this 问题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>state</title>
</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">
         //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>
</body>
</html>

3.5原生事件绑定

<!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>

3.6、react中setState的使用

image.png

3.7、state的简写方式

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>state简写方式</title>
</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">
		//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>
</body>
</html>

``