一个前端菜鸟的React笔记(不全)

262 阅读6分钟

第1章:React入门

一、React简介

1.什么是React?

React是一个用于构建用户界面的Javascript库

作用:

  1. 发送请求获取数据
  2. 处理数据(过滤、整理格式等)
  3. 操作DOM呈现页面

2.谁开发的?

Facebook开发,且开源

3.为什么要学?

原生JavaScript的缺点:

  1. 原生JavaScript操作DOM繁琐、效率低( DOM-API操作UI 比如说一堆的document.getElementById方法获取DOM操作UI)
  2. 使用JavaScript直接操作DOM,浏览器会进行大量的重绘重排
  3. 原生JavaScript没有 组件化 编码方案,代码复用率低

4.React的特点

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

二、React的基本使用

1.相关js库

  1. React.js:React核心库

  2. React-dom.js:提供操作DOM的react拓展库

  3. babel.min.js:提供JSX语法的代码转为JS代码的库

    jsx语法:用于将ES6之后的语法转换为之前版本的,浏览器可以理解的语法,用于提高网站的可阅读性
    

2.引入顺序

  1. 引入React核心库
  2. 引入React-dom,用于支持 react 操作DOM
  3. 引入babel,用于将 jsx 转为 js

3.创建虚拟DOM方法

第一种方式:JSX语法( 需要babel转义 )JSX 是 React语法糖

<script type="text/babel">
    //1.创建虚拟DOM
    const VDOM = <h1>Hello,React</h1>
	//2.渲染虚拟DOM到页面
    ReactDOM.render(VDOM,document.getElementsById("app"))
</script>

第二种方式:原生JS语法 ( 一般不用 )

<scipt type="text/javascript">
    //创建虚拟DOM
    const VDOM = React.createElement("h1",{id:"title",class:"titles"},'Hello React')
    //渲染虚拟DOM到页面
    ReactDOM.render(VDOM,document.getElementById("app"))
</scipt>

4.虚拟DOM

  1. 虚拟dom本质是Object类型的对象( 一般对象 )
  2. 虚拟dom比较 ,真实DOM比较 ,因为虚拟DOM是React内部在用,无需真实DOM上那么多的属性
  3. 虚拟DOM最终会被React转化为真实DOM,呈现在页面上

三、JSX

1.JSX介绍

  1. 全称:JavaScript XML
  2. react定义的一种类似于XML的JS拓展语法: JS-XML
  3. 本质是 React.createElement(component,props, ...children) 方法的语法糖
  4. 作用:用来简化创建虚拟DOM
    • 写法: var element = <h1>Hello JSX </h1>
    • 它不是字符串,也不是HTML/XML标签
    • 它最终产生的就是一个 JS对象
  5. 标签名任意:HTML标签或其他标签
<script type="text/babel">
	 const VDOM = {
		<h2 id="app">
			<span>Hello React</span>
		</h2>
	 }
	 ReactDOM.render(VDOM,document.getElementById("app"))
</script>

2.JSX语法规则

  1. 定义虚拟DOM时,不要写引号
  2. 标签中混入JS表达式时要用 { name }
  3. 使用内联样式需要用双花括号 {{ name }}
  4. 样式的类名要用 className 而不是 class
  5. 虚拟DOM只可以渲染一个根节点,可以使用 React.Fragment
  6. 标签必须闭合
  7. 标签首字母:
    • 若小写字母开头,则将该标签转换为html中同名元素,若html中无对应的同名元素,则报错
    • 若大写字母开头,react就去渲染对应的组件,若组件没有定义,就会报错

四、模块与组件、模块儿化与组件化的理解

1.模块

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

2.组件

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

3.模块化

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

4.组件化

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

第2章:React面向组件编程

一、基本理解与使用

1.React开发者工具调试

打包以后就是正常的React图标

没打包时候时不正常规定React图标

2.效果

  1. 函数式组件

    //1.创建函数式组件
    function Demo(){
    	return <h2>我是函数式组件</h2>
    }
    //2.渲染组件到页面
    ReactDOM.render(<Demo/>,document.getElementById("App"))
    
    /*
    	执行了ReactDOM.render(<Component/>) 之后
    		1.React解析组件标签,找到组件 <Component/>
    		2.发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM渲染为真实DOM,渲染到页面中
    */
    
  2. 类组件

    类的基本知识

    //创建一个Person的类
    class Person{
        //构造器方法
        constructor(name,age){
    		//构造器中的this是谁? —— 类的实例对象
            this.name = name
            this.age = age
        }
        //一般方法
        speak(){
            //speak方法放在了哪里? —— 类的原型对象上,给实例用的
            //通过Person实例调用speak时,speak中的 this 就是 Person实例
            console.log(`我叫${this.name},年龄是${this.age}`)
        }
    }
    //实例化一个对象
    const p1 = new Person('tom',18)
    const p2 = new Person('jerrry',19)
    
    console.log(p1)
    console.log(p2)
    
    p1.speak()
    p2.speak()
    
    //speak中的this不一定就是Person实例
    p1.speak.call({a:1,b:2})
    
    //创建一个Person的类
    class Person{
        //构造器方法 —— 不是必须的
        constructor(name,age){
    		//构造器中的this是谁? —— 类的实例对象
            this.name = name
            this.age = age
        }
        //一般方法
        speak(){
            //speak方法放在了哪里? —— 类的原型对象上,给实例用的
            //通过Person实例调用speak时,speak中的 this 就是 Person实例
            console.log(`我叫${this.name},年龄是${this.age}`)
        }
    }
    
    class Student extends Person{
        constructor(name,age,grade){
            //super方法调用父类的构造器
            super(name,age)
            this.name = name
        }
        //重写从父类继承过来的方法
        speak(){
            console.log(`我叫${this.name},年龄是${this.age},我还是${this.grade}`)
        }
        //study方法放在了类的原型对象上,供实例使用
        study(){
            console.log('我很努力的学习')
        }
    }
    const s1 = new Student('校长','20','县长儿子')
    console.log(s1)
    s1.speak()
    s1.study()
    

    总结:

    1. 类中的构造器不是必须要写的,要对实例进行一些初始化的操作,如添加指定属性时,才写
    2. 如果A类继承了B类,且A类中写了构造器,那么A类构造器中的super时必须要调用的
    3. 类中锁定义的方法,都是放在了类的原型对象上,让实例使用的

    创建类式组件

    //1.创建类组件
    class App extends Component {
      render() {
        return (
          //render 是放在哪里的? —— 类的原型对象上,供实例对象使用
          <div>This is an App</div>
        )
      }
    }
    
    //2.渲染组件到页面
    ReactDOM.createRoot(document.getElementById('root')).render(<App />);
    /*
    	执行了ReactDom。createRoot之后,发生了什么
    		1.React解析组件标签,找到了组件
    		2.发现组件时使用类定义的,随后new出来该类的实例,并通过该实例调用到原型上的render方法
    		3.将render返回的虚拟DOM转为真实DOM,随后呈现在页面中
    */
    

二、组件三大核心属性:state

1.介绍

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

【注意】:

  1. 组件中render方法中的this为实例对象
  2. 组件自定义的方法中 this 为 undefined,如何解决
    1. 强制绑定this:通过函数对象的bind方法
    2. 箭头函数
  3. 状态数据,不能直接修改或更新
  4. 组件三大核心属性

2.使用

//1.创建组件
class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      weather:"hot"
    }
  }
  
  render() {
    console.log(this)
    return (
      <div>This is {this.state.weather} App</div>
    )
  }
}
//2.渲染组件到页面
ReactDOM.createRoot(document.getElementById('root')).render(<App />);

3.事件绑定

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      weather:"hot"
    }
  }
  
  render() {
    console.log(this)
    
    function demo() {
		this.state.weather="cold"
    }
    
    return (
      <div onClick={demo}>This is {this.state.weather} App</div>
    )
  }
}
import React, { Component } from 'react'

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      weather:"hot"
    }
  }
    
  render() {
    console.log(this)
    return (
      <div onClick={this.demo}>This is {this.state.weather} App</div>
    )
  }
    
  	// 方法需要放在原型的对象上,供实例使用
  	// 由于changeWeather是作为onClick的回调,所以不是通过实例调用的,是直接调用
    //类中的方法默认开启了局部的严格模式,所以changeWeather中的this是undefined
  demo() {
    // 通过Weather实例调用changeWeather时
    this.setState.weather="cold"
  }
}

export default App