• 【react-笔记】


    简介

    1. react是什么?
      react是用于构建用户界面的js库(是一个将数据渲染为html视图的开源js库)
    2. 谁开发的?
      在这里插入图片描述
    3. 为什么要学?
      1. 原生js操作dom繁琐、效率低(DOM-API操作UI)
      2. 使用js直接操作dom,浏览器会进行大量的重绘重排
      3. 原生js没有组件化编码方案,代码复用率低
    4. react的特点
      1. 才用组件化模式、声明式编码,提高开发效率及组件复用率
      2. 在ReactNative中可以使用react语法进行移动端开发
      3. 使用虚拟dom+优秀的diffing算法,尽量减少与真实DOM的交互

    基本使用

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
           
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">/*注意:此处一定要写babel*/
        //1.创建虚拟DOM
        const VDOM = (<h1 id="title"><span>hello react</span></h1>)/*注意:此处一定不要写引号,因为不是字符串*/
        //2.渲染虚拟DOM到页面
        ReactDOM.render(VDOM,document.getElementById('app'))/*注意:如果下面还有一模一样的这句话则是覆盖不是追加*/
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    虚拟dom的两种创建方法

    1. jsx (基本使用的写法)
    2. js (一般不用)
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
    body>
    <script type="text/javascript">
        //1.创建虚拟DOM
    	const VDOM = React.createElement('h1',{id:'title'},'hello react')
        //2.渲染虚拟DOM到页面
    	ReactDOM.render(VDOM,document.getElementById('app'))
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    关于虚拟DOM:

    1. 本质是Object类型的对象(一般对象)
    2. 虚拟DOM比较“轻”,真实DOM比较“重”,因为虚拟DOM是React内部再用,无需真实DOM上那么多的属性(轻重指的是身上所有的方法和属性多与少)
    3. 虚拟DOM最终会被React转化为真实DOM,呈现在页面上
      (debugger-浏览器打断点)

    jsx语法规则

    介绍jsx

    1. 全称:JavaScript XML
    2. react定义的一种类似于XML的JS扩张语法:JS+XML
    3. 作用:
      1. 写法:var ele =

        hello react

      2. 注意1. 他不是字符串,也不是HTML/XML标签
      3. 注意2. 他最终产生的就是一个JS对象
    4. 标签名任意:HTML标签或其他标签
      jsx语法规则
    5. 定义虚拟DOM时,不要写引号。
    6. 标签中混入js表达式要用{}
    7. 样式的类名指定不要用class,要用className
    8. 内联样式,要用style={{key:value}}的形式去写(第一个{}:是jsx语法,第二个{}是键值对的写法)
    9. 只有一个跟标签
    10. 标签必须闭合
    11. 标签首字母
      1. 若小写字母开头,则将改标签转为html中同名元素,若html中无该标签对应的同名元素,则报错
      2. 若大写字母开头,react就去渲染对应的组件。若组件没有定义,则报错
    <script type="text/babel">
        let data = 'hello react'
        let dataClsaa='list'
        let arr = ['vue','react','juqery']
        //1.创建虚拟DOM
        const VDOM = (
            <div className={dataClsaa}>
                <h2 style={{color:'red'}}>{data}</h2>    
                <input type="text"/>
                <ul>/*遍历的时候必须要有个key*/
    				{
    					data.map((item,index)=>{
    						return <li key={index}>{item}</li>
    					})
    				}
    			</ul>
            </div>
        )
        //2.渲染虚拟DOM到页面
        ReactDOM.render(VDOM,document.getElementById('app'))
    
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    注意区分:【js语句(代码)】与【js表达式】

    1. 表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方
      下面这些都是表达式:1. a 2. a+b 3. demo(1) 4. arr.map() 5. function test(){}
    2. 语句(代码)
      下面这些都是语句(代码)1. if(){} 2. for(){} 3. switch*(){case:xx}

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

    模块

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

    组件

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

    模块化

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

    组件化

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

    函数式组件

    (简单组件):无状态{state}

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
           
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        //1.创建函数式组件
        function Demo(){/*1.函数名首字母要大写2.函数必须有返回值*/
            console.log(this)//this是undefined(因为babel是严格模式,导致自定义组件的this不指向window)
            return <h2>hello react</h2>
        }
        //2.渲染组件到页面
        ReactDOM.render(<Demo/>,document.getElementById('app'))/*第一个参要写闭合的组件*/
        /*
            执行了ReactDOM.render(,document.getElementById('app'))之后发生了什么?
            1.React解析组件标签,找到了Demo组件(找不见就会报错)
            2.发现组件是使用函数定义的,税后调用该函数,将返回的虚拟DOM转为真实DOM,随后呈现在页面中
        */
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    类式组件

    类复习

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
    
    body>
    <script type="text/javascript">
        //常见一个Person类
        class Person{
            //构造器方法
            constructor(name,age){
                //构造器中的this是谁?——类的实例对象
                this.name = name
                this.age = age
            }
            //类中可以直接写赋值语句
            a=2
            //一般方法:除了构造器的方法,程序员根据业务需求写的方法称之为一般方法
            speak(){
                //speak方法放在哪里?——类的原型对象上,供实例使用
                //通过Person实例调用speak时,speak中的this就是Person实例
                console.log(`我叫${this.name},我的年龄是${this.age}`)
            }
        }
        // const p1 = new Person('tom',18)
        // const p2 = new Person('jerry',19)
        // console.log(p1,p2)
        //创建一个student类,继承于person类
        class Student extends Person{
            constructor(name,age,grade){
                super(name,age)//继承父级-必须在最开始的时候调用super()
                this.grade = grade
            }
            //重写从父类继承过来的方法
            speak(){
                console.log(`我叫${this.name},我的年龄是${this.age},我上${this.grade}`)
            }
            study(){
                //study方法放在哪里?——类的原型对象上,供实例使用
                //通过Student实例调用study时,study中的this就是Student实例
                console.log('我很努力的学习')
            }
        }
        const s1 = new Student('小张',15,'高一')
        console.log(s1)
        /*
            总结:
                1. 类中的构造器不是必须写的,要对实例进行一些初始化的操作,如添加指定属性时才写
                2. 如果a类继承了b类,且a类中写了构造器,那么a类构造器中的super是必须要调用的
                3. 类中所定义的方法,都是放在了类的原型对象上,供实例去使用
        */
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    组件实例三大属性

    state

    类式组件
    (复杂组件):有状态{state}

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        //1.创建类式组件
        class MyComponent extends React.Component{
            //render是放在哪里的?——类的原型对象上,供实例使用
            //render中的this是谁?——MyComponent的实例对象<=>(MyComponent组件实例对象)
            render(){
                console.log(this)
                return <h2>hello react——简单组件(无状态)</h2>
            }
        }
        //2.渲染组件到页面
        ReactDOM.render(<MyComponent/>,document.getElementById('app'))/*第一个参要写闭合的组件*/
        /*
            执行了 ReactDOM.render(,document.getElementById('app'))之后,发生了什么?
                1.react解析组件标签,找到了MyComponent组件
                2.发现组件是使用类定义的,税后new出来该类的实例,并通过该实例调用原型上的render方法
                3.将render返回的虚拟dom转为真实dom,税后呈现在页面中
        */
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        //1.创建类式组件
        class MyComponent extends React.Component{
            constructor(props){
                super(props)
                this.state = {isHot:true}
            }
            render(){
                console.log(this)
                const {isHot} = this.state
                return <h2>今天天气很{isHot?'炎热':'凉爽'}——复杂组件(有状态)</h2>
            }
        }
        //2.渲染组件到页面
        ReactDOM.render(<MyComponent/>,document.getElementById('app'))/*第一个参要写闭合的组件*/
    
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    复杂组件指的是类组件

    复杂组件的事件和更改状态

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        //1.创建类式组件
        class MyComponent extends React.Component{
            //构造器调用几次?——1次
            constructor(props){
                super(props)
                this.state = {isHot:true}
                //注:call会直接执行,而bind是返回一个新的函数,需要手动执行,所以这里只能用bind
                this.demo = this.demo.bind(this)
            }
            //render调用几次?——1+n次 1是初始化的 n是状态更新的次数
            render(){
                const {isHot} = this.state
                //注意:1.点击onClick不要写成onclick 2.调用不要加()如果加会初始化自己会调用
                return <h2 onClick={this.demo}>今天天气很{isHot?'炎热':'凉爽'}</h2>
                //为什么要改变this指向是因为οnclick=this.demo本质意义上
                //并没有调用而是直接把这个方法复制过来,(浅拷贝)所以this为undefined
            }
            demo(){
                //demo放在哪里?——MyComponent的原型对象上,供实例使用
                //由于demo是作为onClick的回调,所以不是通过实例调用的,是直接调用
                //类中的方法默认开启了局部的严格模式,所以demo中的this为undefined
               const isHot = this.state.isHot
               //注意:状态(state)不可直接更改,下面这行就是直接更改
               //this.state.isHot = !isHot//这是错误的写法
               //严重注意:状态必须通过setState进行更新,且更新是一种合并,不是替换。
               this.setState({isHot:!isHot})
            }
        }
        //2.渲染组件到页面
        ReactDOM.render(<MyComponent/>,document.getElementById('app'))/*第一个参要写闭合的组件*/
        
    
        /*
            bind:
            function demo(){
                console.log(this)
            }
            //demo.bind({a:1})//直接这么写不会执行,需要调用才会执行
            const x = demo.bind({a:1})
            x()
        */
        
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    以上代码简写形式

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        //1.创建类式组件
        class MyComponent extends React.Component{
            constructor(props){
                super(props)
                // this.state = {isHot:true}
                // this.demo = this.demo.bind(this)
            }
            state = {isHot:true} //类中可以直接写赋值语句
            render(){
                const {isHot} = this.state
                return <h2 onClick={this.demo}>今天天气很{isHot?'炎热':'凉爽'}</h2>
            }
            //自定义方法——要用赋值语句的形式+箭头函数
            demo=()=>{
               const isHot = this.state.isHot
               this.setState({isHot:!isHot})
            }
        }
        //2.渲染组件到页面
        ReactDOM.render(<MyComponent/>,document.getElementById('app'))
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    理解:

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

    强烈注意:

    1. 组件中render方法中的this为组件实例对象
    2. 组件自定义的方法中this为undefined,如何解决?
      1. 强制绑定this通过函数对象的bind()
      2. 箭头函数
    3. 状态数据,不能直接修改或更新
    props
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        <div id="test">
    
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
        
        <script src="https://unpkg.com/prop-types@15.6/prop-types.min.js">script>
    body>
    <script type="text/babel">
        //1.创建类式组件
        class MyComponent extends React.Component{
            render(){
                //props是只读的
                const {name,age} = this.props
                console.log(this)
               return (
                    <ul>
                        <li>姓名:{name}</li>    
                        <li>性别:{age+1}</li>    
                    </ul>
               )
            }
        }
        MyComponent.propTypes={
            //name:ProtoTypes.string//这种写法在16.xxx写法可以
            //name:React.PropTypes这种写法在15.5xx版本之前可以,在16.xxx就被弃用了
            name:PropTypes.string.isRequired,//string必须是string+isRequired必填项
            age:PropTypes.number
            //function=>.func——限制函数
        }
        MyComponent.defaultProps={
            age:50
        }
        const p = {name:'lisa',age:18}
        //2.渲染组件到页面
        ReactDOM.render(<MyComponent name="tom" age="18"/>,document.getElementById('app'))
         ReactDOM.render(<MyComponent {...p}/>,document.getElementById('test'))//{...p}=>由于react+babel导致允许你在标签中这样写,不然拓展运算符是不可以展开对象的
        /*
            展开运算符:
                let arr1 = [1,2,3,4]
                let arr2 = [7,8,9,6]
                console.log(...arr1)//1.展开一个数组
                let arr3 = [...arr1,...arr2] 
                console.log(arr3)//2.连接数组
                function sum(...numbers){//求和
                    return numbers.reduce((preValue,currentValue)=>{
                        return preValue+currentValue
                    })
                }
                sum(1,5,6,7)//3.函数传参
                let person = {name:'tom',age:18} 
                let person2 = {...person}//深拷贝
                console.log(...person)//报错,展开运算符不能展开对象
        */
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    props简写

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        <div id="test">
    
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
        
        <script src="https://unpkg.com/prop-types@15.6/prop-types.min.js">script>
    body>
    <script type="text/babel">
        //1.创建类式组件
        class MyComponent extends React.Component{
            //对标签属性进行类型、必要性的限制
            static propTypes={
                name:React.PropTypes.string.isRequired,
                age:React.PropTypes.number
            }
            //指定默认标签属性值
            static defaultProps={
                age:50
            }
            render(){
                //props是只读的
                const {name,age} = this.props
                console.log(this)
               return (
                    <ul>
                        <li>姓名:{name}</li>    
                        <li>性别:{age+1}</li>    
                    </ul>
               )
            }
            
        }
     
        const p = {name:'lisa',age:18}
        //2.渲染组件到页面
        ReactDOM.render(<MyComponent name="tom" age="18"/>,document.getElementById('app'))
         ReactDOM.render(<MyComponent {...p}/>,document.getElementById('test'))//{...p}=>由于react+babel导致允许你在标签中这样写,不然拓展运算符是不可以展开对象的
    
    script>
    html>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    构造器

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        <div id="test">
    
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
        
        <script src="https://unpkg.com/prop-types@15.6/prop-types.min.js">script>
    body>
    <script type="text/babel">
        //1.创建类式组件
        class MyComponent extends React.Component{
            //构造器_类中的构造器基本不会使用
            constructor(props){
                //构造器是否接受props,是否传递给super,取决于:是否希望在构造器中通过this访问props
                super(props)
                console.log(props)
            }
            //对标签属性进行类型、必要性的限制
            static propTypes={
                name:React.PropTypes.string.isRequired,
                age:React.PropTypes.number
            }
            //指定默认标签属性值
            static defaultProps={
                age:50
            }
            render(){
                //props是只读的
                const {name,age} = this.props
                console.log(this)
               return (
                    <ul>
                        <li>姓名:{name}</li>    
                        <li>性别:{age+1}</li>    
                    </ul>
               )
            }
            
        }
     
        const p = {name:'lisa',age:18}
        //2.渲染组件到页面
        ReactDOM.render(<MyComponent name="tom" age="18"/>,document.getElementById('app'))
         ReactDOM.render(<MyComponent {...p}/>,document.getElementById('test'))//{...p}=>由于react+babel导致允许你在标签中这样写,不然拓展运算符是不可以展开对象的
    
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    函数式组件获取props

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        <div id="test">
    
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
        
        <script src="https://unpkg.com/prop-types@15.6/prop-types.min.js">script>
    body>
    <script type="text/babel">
        function MyComponent(props) {
            console.log(props)
            return (
                    <ul>
                        <li>姓名:{name}</li>    
                        <li>性别:{age}</li>    
                    </ul>
               )
        }
        //对标签属性进行类型、必要性的限制
        MyComponent.propTypes={
            name:React.PropTypes.string.isRequired,
            age:React.PropTypes.number
        }
            //指定默认标签属性值
        MyComponent.defaultProps={
            age:50
        }
        //2.渲染组件到页面
        ReactDOM.render(<MyComponent name="tom" age="18"/>,document.getElementById('app'))
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    refs

    勿过渡使用ref
    什么时候不使用ref而使用event?
    发生事件的元素正好是你要操作的元素的时候

    字符串形式的ref(过时的api——)
    不建议使用(string的ref存在一些效率问题——效率不高)

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        //1.创建类式组件
        class MyComponent extends React.Component{
            render(){
               return (
                    <ul>
                        <li ref="name" onClick={this.demo}>姓名:lily</li>    
                        <li>性别:女</li>    
                    </ul>
               )
            }
            demo = ()=>{
                console.log(this.refs.name)
            }
            
        }
     
        //2.渲染组件到页面
        ReactDOM.render(<MyComponent/>,document.getElementById('app'))
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    回调形式的ref

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        //1.创建类式组件
        class MyComponent extends React.Component{
            render(){
               return (
                    <ul>
                        {/*内联函数写法(一般工作中这种写法比较多):
  • this.input1 = currentNode} onClick={this.demo}>姓名:lily
  • */
    } <li ref={this.getrefs}>性别:女</li> </ul> ) /* 回调ref中调用执行次数的问题:如图 内联写法和定义成class绑定函数的区别:(无关紧要——不会有多大的影响)内联函数更新的时候会触发两次 一次为null一次为当前节点 */ /*ref={currentNode=>this.input1 = currentNode} <=> ref={(a)=>{this.input1 = a}} 意义:把ref当前所处的节点挂载了实例自身上并且取了一个名字教input1*/ } getrefs=(c)=>{ this.input1 = c } demo = ()=>{ const {input1} = this console.log(input1) } } //2.渲染组件到页面 ReactDOM.render(<MyComponent/>,document.getElementById('app'))
    script> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    在这里插入图片描述
    createRef

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        //1.创建类式组件
        class MyComponent extends React.Component{
            //React.createRef调用后可以返回一个容器,改容器可以存储被ref所标识的节点
           //该容器是“专人专用”的
           //每用一个就要写一个下面的
            myRef = React.createRef()
            myRef2 = React.createRef()
            render(){
               return (
                    <ul>
                        <li ref={this.myRef} onClick={this.demo}>姓名:lily</li>   
                        <li ref={this.myRef2} onClick={this.demo2}>性别:女</li>     
                    </ul>
               )
            }
            demo = ()=>{
                console.log(this.myRef.current)
            }
            demo2 = ()=>{
                console.log(this.myRef2.current)
            }
            
        }
     
        //2.渲染组件到页面
        ReactDOM.render(<MyComponent/>,document.getElementById('app'))
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    事件处理

    1. 通过onXxx属性指定事件处理函数(注意大小写)
      1. React使用的是自定义(合成)事件,而不是使用的原生DOM事件——为了更好的兼容性
      2. React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)——为了高效
    2. 通过event.target得到发生事件的DOM元素对象.——不要过渡的使用ref
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        //1.创建类式组件
        class MyComponent extends React.Component{
            dot=(event)=>{
                console.log(event.target)
            }
            render(){
               return (
                    <ul>
                        <li onClick={this.dot}>点我一下</li>
                    </ul>
               )
            }
        }
        //2.渲染组件到页面
        ReactDOM.render(<MyComponent/>,document.getElementById('app'))
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    包含表单的组件分类

    非受控组件

    所有输入类的DOM(checkbox、radio、input...)现用现取

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        //1.创建类式组件
        class MyComponent extends React.Component{
            handleSubmit=(event)=>{
                event.preventDefault();//阻止默认事件
                const {username,password} = this
                alert(`用户名${username.value}密码${password.value}`)
            }
            render(){
               return (
                    <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>
               )
            }
        }
        //2.渲染组件到页面
        ReactDOM.render(<MyComponent/>,document.getElementById('app'))
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    受控组件

    页面中所有输入类的DOM,随着输入,就会把你输入的内容维护到状态里面去,等需要用的时候直接从状态里去拿

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        //1.创建类式组件
        class MyComponent extends React.Component{
            // 初始化状态
            state={
                username:'',
                password:''
            }
            // 表单提交问题
            handleSubmit=(event)=>{
                event.preventDefault();//阻止默认事件
                const {username,password} = this.state
                console.log(username,password)
            }
            // 保存用户名到状态中
            getUsername=(event)=>{
                this.setState({username:event.target.value})
            }
            // 保存密码到状态中
            getPassword=(event)=>{
                this.setState({password:event.target.value})
            }
            render(){
               return (
                    <form onSubmit={this.handleSubmit}>
                        用户名:<input onChange={this.getUsername} type="text" name="username"/>
                        密码:<input onChange={this.getPassword}   type="password" name="password"/>
                        <button>登录</button>
                    </form>
               )
            }
        }
        //2.渲染组件到页面
        ReactDOM.render(<MyComponent/>,document.getElementById('app'))
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    建议使用受控组件,因为受控组件中未使用ref

    高阶函数_函数的柯里化

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        //1.创建类式组件
        class MyComponent extends React.Component{
            // 初始化状态
            state={
                username:'',
                password:''
            }
            // 获取表单数据到状态中
            handleSubmit=(event)=>{
                event.preventDefault();//阻止默认事件
                const {username,password} = this.state
                console.log(username,password)
            }
            getFormData=(dataType)=>{
                console.log(dataType)
                return (event)=>{//这种写法是有返回值的(返回的函数)————onChange调用的函数获取的就是event
                    this.setState({[dataType]:event.target.value})
                }
            }
            render(){
               return (
                    <form onSubmit={this.handleSubmit}>
                        {/*
                        onChange={this.getFormData('username')}————这种写法的意思是把这个函数getFormData的返回值作为onchange回调——(因为他的返回值是undefined所以就没有效果)
                        getFormData=(event)=>{//这种写法的返回值为undefined
                            this.setState({username:event.target.value})
                        }
                    */}
                    {/**/}
                        用户名:<input onChange={this.getFormData('username')} type="text" name="username"/>
                        密码:<input onChange={this.getFormData('password')}   type="password" name="password"/>
                        <button>登录</button>
                    </form>
               )
            }
        }
        //2.渲染组件到页面
        ReactDOM.render(<MyComponent/>,document.getElementById('app'))
        /*
            对象相关的知识:
                let a ='name'
                let obj = {}
                obj[a]='tom'
                console.log(obj)
        */
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    高阶函数:如果一个函数符合下面2个规范中的任何一个,那该函数就是高阶函数
    1. 若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数
    2. 若A函数,调用的参数是一个函数,那么A就可以称之为高阶函数
    常见的高阶函数有:promise setTimeout arr.map()
    函数的柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式
    (让注释代码折叠:#region/**/#endregion)

    不用柯里化的写法

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        //1.创建类式组件
        class MyComponent extends React.Component{
            // 初始化状态
            state={
                username:'',
                password:''
            }
            // 获取表单数据到状态中
            handleSubmit=(event)=>{
                event.preventDefault();//阻止默认事件
                const {username,password} = this.state
            }
            getFormData=(dataType,value)=>{
                this.setState({[dataType]:event.target.value})
            }
            render(){
               return (
                    <form onSubmit={this.handleSubmit}>
                        用户名:<input onChange={(event)=>{this.getFormData('username',event)}} type="text" name="username"/>
                        密码:<input onChange={(event)=>{this.getFormData('password',event)}}   type="password" name="password"/>
                        <button>登录</button>
                    </form>
               )
            }
        }
        //2.渲染组件到页面
        ReactDOM.render(<MyComponent/>,document.getElementById('app'))
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    生命周期

    引出生命周期

    componentDidMount——组件挂载完毕
    componentWillUnmount——组件将要卸载
    render——初始化渲染‘状态更新之后’

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        //1.创建类式组件
        class Life extends React.Component{
            /*
                状态
            */
            state = {
                opacity:1
            }
            /*
                方法
            */
            death = ()=>{
                // 卸载组件
                ReactDOM.unmountComponentAtNode(document.getElementById('app'))
            }
            /*
                生命周期
            */
            //组件挂载完毕
            componentDidMount(){//只执行一次
                this.timer=setInterval(() => {
                    //获取原状态
                    let {opacity} = this.state
                    //减小0.1
                    opacity-=0.1
                    if(opacity<=0) opacity=1
                    //设置新的透明度
                    this.setState({opacity})
                }, 200);
            }
            //组件将要卸载
            componentWillUnmount(){
                //清除定时器
                clearInterval(this.timer)
            }
            /*
                初始化渲染
            */
            render(){
               return (
                    <div>
                        <h2 style={{opacity:this.state.opacity}} >学不会react怎么办?</h2>  
                        <button onClick={this.death}>不活了</button>  
                    </div>
               )
            }
        }
        //2.渲染组件到页面
        ReactDOM.render(<Life/>,document.getElementById('app'))
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    理解
    1. 组件从创建到死亡会经历一些特定的阶段
    2. react组件中包含一系列钩子函数(生命周期回调函数),会在特定的时刻调用
    3. 我们在定义组件时,会在特定的生命周期回调函数,中做特定的工作
    生命周期(旧)

    在这里插入图片描述

    shouldComponentUpdate默认是true 即使不调用

    挂载时

    DOCTYPE html>
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        class Count extends React.Component{
            // 构造器
            constructor(props){
                console.log('count-constructor')
                super(props)
                this.state={count:0}
            }
            
            
            add=()=>{
                const {count} = this.state
                this.setState({count: count+1})
            }
            death=()=>{
                ReactDOM.unmountComponentAtNode(document.getElementById('app'))
            }
            // 组件将要挂载的钩子
            componentWillMount(){
                console.log('count-componentWillMount')
            }
            // 组件挂载完毕的钩子
            componentDidMount(){
                console.log('count-componentDidMount')
            }
            // 组件将要卸载的钩子
            componentWillUnmount(){
                console.log('count-componentWillUnmount')
            }
            render(){
                console.log('count-render')
                const {count} = this.state
                return(
                    <div>
                        <div>{count}</div>
                        <div onClick={this.add}>点击+1</div> 
                        <div onClick={this.death}>点击卸载组件</div>   
                    </div>
                )
            }
        }
        
        //2.渲染组件到页面
        ReactDOM.render(<Count/>,document.getElementById('app'))
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    父组件render
    路线一

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        class Count extends React.Component{
            // 构造器
            constructor(props){
                console.log('count-constructor')
                super(props)
                this.state={count:0}
            }
            
            
            add=()=>{
                const {count} = this.state
                this.setState({count: count+1})
            }
            death=()=>{
                ReactDOM.unmountComponentAtNode(document.getElementById('app'))
            }
            // 组件将要卸载的钩子
            componentWillUnmount(){
                console.log('count-componentWillUnmount')
            }
            //控制组件更新的阀门
            shouldComponentUpdate(){
                console.log('count-shouldComponentUpdate')
                return true
            }
            //组件将要更新的钩子
            componentWillUpdate(){
                console.log('count-componentWillUpdate')
            }
            // 组件更新完毕的钩子
            componentDidUpdate(){
                console.log('count-componentDidUpdate')
            }
            render(){
                console.log('count-render')
                const {count} = this.state
                return(
                    <div>
                        <div>{count}</div>
                        <div onClick={this.add}>点击+1</div> 
                        <div onClick={this.death}>点击卸载组件</div>   
                    </div>
                )
            }
        }
        
        //2.渲染组件到页面
        ReactDOM.render(<Count/>,document.getElementById('app'))
    script>
    html>         
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    路线二

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        class Count extends React.Component{
            // 构造器
            constructor(props){
                console.log('count-constructor')
                super(props)
                this.state={count:0}
            }
            
            
            add=()=>{
                const {count} = this.state
                this.setState({count: count+1})
            }
            death=()=>{
                ReactDOM.unmountComponentAtNode(document.getElementById('app'))
            }
            //强制更新
            force=()=>{
                this.forceUpdate()
            }
            // 组件将要卸载的钩子
            componentWillUnmount(){
                console.log('count-componentWillUnmount')
            }
            //控制组件更新的阀门
            shouldComponentUpdate(){
                console.log('count-shouldComponentUpdate')
                return false
            }
            //组件将要更新的钩子
            componentWillUpdate(){
                console.log('count-componentWillUpdate')
            }
            // 组件更新完毕的钩子
            componentDidUpdate(){
                console.log('count-componentDidUpdate')
            }
            render(){
                console.log('count-render')
                const {count} = this.state
                return(
                    <div>
                        <div>{count}</div>
                        <div onClick={this.add}>点击+1</div> 
                        <div onClick={this.death}>点击卸载组件</div>   
                        <div onClick={this.force}>不更改状态,强制更新</div>
                    </div>
                )
            }
        }
        
        //2.渲染组件到页面
        ReactDOM.render(<Count/>,document.getElementById('app'))
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    路线三

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        class A extends React.Component{
            state = {carName:'奔驰'}
            changeCar = ()=>{
                this.setState({carName:'奥迪'})
            }
            render(){
                return (
                    <div>
                        <div>a</div>
                        <button onClick={this.changeCar}>换车</button>
                        <B carName={this.state.carName}/>
                    </div>
                )
            }
        }
        class B extends React.Component{
            //将要props(需要新的,意思就是刚接收的不算,只有新的在算)
            componentWillReceiveProps(){
                console.log('b')
            }
             //控制组件更新的阀门(必须要return布尔值)
             shouldComponentUpdate(){
                console.log('b-shouldComponentUpdate')
                return true
            }
             //组件将要更新的钩子
             componentWillUpdate(){
                console.log('b-componentWillUpdate')
            }
            // 组件更新完毕的钩子
            componentDidUpdate(){
                console.log('b-componentDidUpdate')
            }
            render(){
                console.log('b---render')
                return (
                    <div>b  {this.props.carName}</div>
                )
            }
        }
        //2.渲染组件到页面
        ReactDOM.render(<A/>,document.getElementById('app'))
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    总结

       /*
            1.初始化阶段:由ReactDOM。render()触发————初次渲染
                        1.constructor()
                        2.componentWillMount()
                        3.render()
                        4.componentDidMount()
            2.更新阶段:由组件内部this.setState()或父组件重新render触发
                        1.shouldComponentUpdate()
                        2.componentWillUpdate()
                        3.render()
                        4.componentDidUpdate()
            3.卸载组件:由ReactDOM.unmountComponentAtNode()触发
                        1.componentWillUnmount()
    
        */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    新的生命周期

    对比旧的生命周期
     /*在新版本里,旧的生命周期前面需要加 UNSEFE_  来解决警告 只有一下三个需要加
            1.componentWillMount
            2.componentWillReceiveProps
            3.componentWillUpdate
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    新的生命周期
    /*挂载时*/
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        class Count extends React.Component{
            // 构造器
            constructor(props){
                console.log('count-constructor')
                super(props)
                this.state={count:0}
            }
            
            
            add=()=>{
                const {count} = this.state
                this.setState({count: count+1})
            }
            death=()=>{
                ReactDOM.unmountComponentAtNode(document.getElementById('app'))
            }
            force=()=>{
                this.forceUpdate()
            }
            // 组件将要卸载的钩子
            componentWillUnmount(){
                console.log('count-componentWillUnmount')
            }
            //控制组件更新的阀门
            shouldComponentUpdate(){
                console.log('count-shouldComponentUpdate')
                return false
            }
            // 组件更新完毕的钩子
            componentDidUpdate(){
                console.log('count-componentDidUpdate')
            }
            //派生组件会导致代码沉余,并使用组件难以维护(了解即可)
            static getDerivedStateFromProps(props,state){//基本上以后用不到
                //props是传的值
                console.log('getDerivedStateFromProps',props,state)//必须有返回值:第一种返回值是个状态对象,第二种返回值是null
                return props//一旦返回状态对象,那么状态的更新就不执行了__若state值在任何时候都取决于props(这是其中一种解决办法,还有一种解决办法就是在构造器中给状态对象赋值props即可),那么可以使用
                //return null  不影响功能
            }
            render(){
                console.log('count-render')
                const {count} = this.state
                return(
                    <div>
                        <div>{count}</div>
                        <div onClick={this.add}>点击+1</div> 
                        <div onClick={this.death}>点击卸载组件</div>   
                        <div onClick={this.force}>不更改状态,强制更新</div>
                    </div>
                )
            }
        }
        //2.渲染组件到页面
        ReactDOM.render(<Count count="199"/>,document.getElementById('app'))
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    /*更新时*/
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        class Count extends React.Component{
            // 构造器
            constructor(props){
                console.log('count-constructor')
                super(props)
                this.state={count:0}
            }
            
            
            add=()=>{
                const {count} = this.state
                this.setState({count: count+1})
            }
            death=()=>{
                ReactDOM.unmountComponentAtNode(document.getElementById('app'))
            }
            force=()=>{
                this.forceUpdate()
            }
            // 组件将要卸载的钩子
            componentWillUnmount(){
                console.log('count-componentWillUnmount')
            }
            //控制组件更新的阀门
            shouldComponentUpdate(){
                console.log('count-shouldComponentUpdate')
                return false
            }
            // 组件更新完毕的钩子
            componentDidUpdate(preProps,preState,snapshotValue){
                console.log('count-componentDidUpdate',preProps,preState,snapshotValue)
            }
            //派生组件会导致代码沉余,并使用组件难以维护(了解即可)
            static getDerivedStateFromProps(props,state){//基本上以后用不到
                //props是传的值
                console.log('getDerivedStateFromProps',props,state)//必须有返回值:第一种返回值是个状态对象,第二种返回值是null
                return null//一旦返回状态对象,那么状态的更新就不执行了__若state值在任何时候都取决于props(这是其中一种解决办法,还有一种解决办法就是在构造器中给状态对象赋值props即可),那么可以使用
                //return null  不影响功能
            }
            //在更新之前获取快照
            getSnapshotBeforeUpdate(){
                console.log('getSnapshotBeforeUpdate')//有返回值:字符串或者null
                return 'null'
            }
            render(){
                console.log('count-render')
                const {count} = this.state
                return(
                    <div>
                        <div>{count}</div>
                        <div onClick={this.add}>点击+1</div> 
                        <div onClick={this.death}>点击卸载组件</div>   
                        <div onClick={this.force}>不更改状态,强制更新</div>
                    </div>
                )
            }
        }
        //2.渲染组件到页面
        ReactDOM.render(<Count count={199}/>,document.getElementById('app'))
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    /*getSnapshotBeforeUpdate_-___案例*/
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
        <style>
            .list{
                width: 200px;
                height: 210px;
                max-height: 210px;
                overflow: auto;
                background: bisque;
            }
            .news{
                height: 30px;
            }
        style>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        class Count extends React.Component{
            state = {newsArr:[]}
            
            componentDidMount(){
                setInterval(() => {
                    const {newsArr} = this.state
                    //模拟一条新闻
                    const news = '新闻'+(newsArr.length+1)
                    //更新状态
                    this.setState({newsArr:[news,...newsArr]})
                }, 1000);
            }
            getSnapshotBeforeUpdate(){
                return this.refs.list.scrollHeight
            }
            componentDidUpdate(preProps,preState,height){
                this.refs.list.scrollTop += this.refs.list.scrollHeight - height
            }
            render(){
               
                return(
                    <div className="list" ref="list">
                        {
                            this.state.newsArr.map((n,index)=>{
                                return <div  key={index} className="news">{n}</div>
                            })
                        }
                    </div>
                )
            }
        }
        //2.渲染组件到页面
        ReactDOM.render(<Count count={199}/>,document.getElementById('app'))
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    总结

    /*
            1.初始化阶段:由ReactDOM.render()触发——————初次渲染
                    1.constructor()
                    2.getDeriverStateFromProps
                    3.render()
                    4.componentDidMount
            2.更新阶段:由组件内部this.setState()或父组件重新render触发
                    1.getDerivedStateFromProps
                    2.shouldComponentUpdate()
                    3.render()
                    4.getSnapshotBeforeUpdate
                    5.componentDidUpdate
            3.卸载组件:由ReactDom.unmountComponentAtNode()触发
                    1.componentWillUnmount()
    
        */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    DOM的diffing算法

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <div id="app">
          
        div>
        
        
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js">script>
        
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">script>
        
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    body>
    <script type="text/babel">
        /*
            问题:
                1. react/vue中的key有什么作用?(key的内部原理是什么?)
                2.为什么遍历列表时,key最好不要用index?
            答案:
            1.虚拟dom中key的作用:
                1)简单的说:key是虚拟DOM对象的标识,在更新显示时key起着极其重要的作用
                2)详细的说:当状态中的数据发生变化时,react会根据【新数据】生成【新的虚拟dom】,
                            随后react进行【新的虚拟DOM】与【旧虚拟DOM】的diff比较,比较规则如下:
                        a.旧虚拟DOM中找了与新虚拟DOM相同的key
                            1)若虚拟DOM中内容没变,直接使用之前的真实DOM
                            2)若虚拟DOM中内容变了,则生成新的真实DOM,随后替换页面中之前的真实DOM
                        b.旧虚拟DOM中未找到与新虚拟DOM相同key
                            根据数据创建新的真实DOM,随后渲染到页面
            2.用index作为key可能会引发的问题
                1)若对数据进行:逆序添加‘逆序删除等破坏顺序操作:
                        会产生没有必要的真实DOM更新===》界面效果没问题,但效率低
                2)如果结构中还包含输入类的DOM:
                        会产生错误DOM更新==》界面有问题
                3)注意:如果不存在对数据的逆序添加’逆序删除等破坏顺序操作
                    仅用于渲染列表用于展示,使用index作为key是没有问题的
            3.开发中如何选择key?
                1.最好使用每条数据的唯一标识作为key,比如id...
                2.如果确定只是简单的展示数据、用index也是可以的-
    
    
        */
    //    class Time extends React.Component{
    //     state = {date:new Date()}
    //     componentDidMount(){
    //         setInterval(()=>{
    //             this.setState({
    //                 date:new Date()
    //             })
    //         },1000)
    //     }
    //     render(){
    //         return (
    //             
    // // {this.state.date.toTimeString()} //
    // ) // } // } //2.渲染组件到页面 ReactDOM.render(<Time />,document.getElementById('app'))
    script> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
  • 相关阅读:
    谷粒商城篇章6 ---- P193-P210 ---- 异步&线程池&商品详情【分布式高级篇三】
    gorm Preload与Joins带条件查询--闭坑指南与示例
    『牛客|每日一题』走迷宫
    system verilog 处理子进程(关闭/等待/跳转)
    用visa进行仪表通信
    【对象存储】Minio本地运行和 golang客户端基本操作
    阮一峰的ES6文档(第一天)
    K8S:配置资源管理 Secret和configMap
    C++ string 类的其他操作
    【Java每日一题】— —第十九题:用二维数组存放九九乘法表,并将其输出。(2023.10.03)
  • 原文地址:https://blog.csdn.net/weixin_47416539/article/details/127401447