React学习记录

一、简介

1、React是什么?

一个将数据渲染为HTML视图的开源JavaScript库,操作DOM呈现页面。

2、特点

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

二、案例体验

旧版本:16.x,新版本:18.x

依赖包认识:

  • babel.min.js:将ES6转成ES5,将JSX转成JS
  • react.development.js:核心库
  • react-dom.development.js:扩展库
  • prop-type.js

使用本地开发环境创建一个项目:

npx create-react-app my-app

删除掉新项目中 src/ 文件夹下的所有文件。删除掉新项目中 src/ 文件夹下的所有文件。

引入3个依赖包,引入顺序:react.development.js、react-dom.development.js、babel.min.js(没有老师的这个文件,可以直接引入官方网站)

1、创建虚拟DOM

2、渲染虚拟DOM到页面



  
    
    
    
    Document
    
    
    
    
    
    
  
  
    
    

效果:

React学习记录_第1张图片

下载开发者工具:

三、虚拟DOM

注意:

 1、用jsx创建虚拟DOM

    

2、用js创建虚拟DOM

    

创建多个虚拟DOM,jsx更方便

3、虚拟DOM就是一个Object类型的对象,即一般对象

4、与真实DOM的区别:consolog输出的真实DOM就是标签及内容,用断点查看会看到真实DOM身上的属性很多,而虚拟DOM身上的属性只有几个 =》原因:虚拟DOM是react内部在用,无需真实DOM

5、虚拟DOM最终会被react转化为真实DOM显示在页面上

四、jsx

jsx = js +XML,是react创造的

语法规则:

1、定义虚拟DOM时,不需要写引号,因为不是字符串

2、标签中混入js表达式(≠ js代码=js代码)时用{ }包裹,且变量内容大小写都有时要转换成小写

3、样式的类名不要写class,要写classname

4、内联样式,用{{ }}包裹,因为样式style里是key-value组成的形式,但是jsx里不能这么写,需要写成对象形式。多个样式时,用逗号隔开,且样式属性名只能用驼峰写法

5、虚拟DOM只能有1个根标签

6、标签要闭合

7、标签首字母为小写,标签转为html同名标签,无同名标签就报错。标签首字母为大写,标签渲染同名组件,找不到该组件就报错

  
    
    

案例:

关于遍历数据,只能遍历数组,不能遍历对象。

纯数组数据jsx无法渲染出来,但是数据如果是jsx形式就可以被直接渲染到页面,但很显然后端是不会提供这种形式的数据的

遍历时不能少了key,会报错

  
    
    

五、模块化与组件化

React学习记录_第2张图片

六、脚手架

安装开发工具:

React学习记录_第3张图片

七、组件

1、函数式组件

  
    
    

执行render后发生了什么?

(1)react解析组件标签,找到组件

(2)发现组件是函数定义的,调用该函数,返回的虚拟DOM转换为真实DOM,渲染到页面

2、类组件

  
    
    

执行render后发生了什么?

(1)react解析组件标签,找到组件

(2)发现组件是类定义的,new该类的实例,并通过实例调用原型的render方法

(3)将render返回的虚拟DOM转换为真实DOM,渲染到页面

八、组件实例的三大属性——state  状态

1、初始化state + 事件绑定 + 修改方法的this指向:

  
    
    

注意两个this后指的是什么:

React学习记录_第4张图片

2、setState:修改数据

        changeWeather() {
          // changeWeather放在Weather的原型对象上,供实例使用
          // changeWeather作为onClick的回调,不是通过实例调用的而是直接调用
          // 类中的方法默认开启了局部的严格模式,所以changeWeather的this是undefined
          // console.log(this);
          // this.state.isHot = !this.state.isHot;  // 数据是不能直接改的,直接改没法渲染
          const isHot = this.state.isHot;
          // setState修改数据,更新是新旧数据的合并,只修改改变的,不变的数据没有丢失依旧不变
          this.setState({ isHot: !this.state.isHot });
        }

组件的构造器调用1次,render就调用n+1次,n次是状态更新的次数,方法用几次就调用几次

3、简写

(1)state可以不写在构造器里,单独写出来,与render同级

(2)自定义方法写成赋值语句+箭头函数,满足修改this指向

        changeWeather = () => {
          // changeWeather放在Weather的原型对象上,供实例使用
          // changeWeather作为onClick的回调,不是通过实例调用的而是直接调用
          // 类中的方法默认开启了局部的严格模式,所以changeWeather的this是undefined
          // console.log(this);
          // this.state.isHot = !this.state.isHot;  // 数据是不能直接改的,直接改没法渲染
          const isHot = this.state.isHot;
          // setState修改数据,更新是新旧数据的合并,只修改改变的,不变的数据没有丢失依旧不变
          this.setState({ isHot: !this.state.isHot });
        }

九、组件实例的三大属性——props

1、基本实现

在组件标签上以key-value形式写的变量,实例里用this.props.变量名呈现

  
    
    

解构简写:

  
    
    

2、批量处理

用...展开运算符,这里是浅拷贝的意思,不是将对象展开,...是无法展开对象的

  
    
    

3、限制props的数据形式

15版本之前,react有一个属性propTypes可以限制,之后版本就用到prop-types包

    
    

限制函数写成=》PropTypes.func

  
    
    

4、props只读不改

5、简写

将propTypes、defaultProps写成静态方法,放在类里

      class Person extends React.Component {
        // 限制标签属性值类型
        static propTypes = {
          name: PropTypes.string.isRequired, // 限制name为字符串,且必须有
        };
        // 给标签属性值设置默认值
        static defaultProps = {
          age: 18,
        };

        render() {
          console.log(this); // Person实例
          const { name, age, sex } = this.props;
          return (
            
  • name: {name}
  • sex: {sex}
  • age: {age}
  • speak: {speak}
); } }

6、构造器与props

在构造器里可以不写props,但是用this无法找到当前类的props

        constructor(props) {
          super(props);
          console.log(this.props);
        }
        constructor() {
          super();
          console.log(this.props);  // undefined
        }

7、函数式组件的props

  
    
    

8、总结

React学习记录_第5张图片React学习记录_第6张图片

十、组件实例的三大属性——ref

1、字符串形式(已过时)

React学习记录_第7张图片

2、回调形式

React学习记录_第8张图片

3、回调执行次数

React学习记录_第9张图片

React学习记录_第10张图片

4、createRef 

调用后可以返回一个容器,该容器可以存储被ref标识的节点,该容器专节点专用(也就是会被新的覆盖)

React学习记录_第11张图片

5、何时使用&不要过度使用React学习记录_第12张图片

十一、事件处理

React学习记录_第13张图片

发生事件的元素和操作事件的元素是同一个,可以省略ref

十二、非受控组件与受控组件

1、非受控组件

元素现用现取,用ref,如form里的input

2、受控组件

元素不是现用现取,不用ref

十三、函数柯里化

 

十四、生命周期(生命周期钩子函数,生命周期回调函数)

注意!生命周期钩子函数的书写顺序与react调用顺序无关,react会在该调用的时候调用

卸载组件ReactDOM.unmountComponentAtNode  (记忆:卸载组件在节点)

componentDidMount:组件挂载完毕

render:初始化渲染、状态更新之后

React学习记录_第14张图片

1、旧生命周期(16.x版本)

React学习记录_第15张图片

(1)组件挂载过程

(2)组件更新过程

第一条路:正常更新

React学习记录_第16张图片

shouldComponentUpdate:控制组件是否更新,默认值true,如果程序员不亲自写则保持默认值,如果亲自写成false则永远无法更新状态 

第二条路:强制更新

应用场景:不想对状态中的数据更新,但想更新页面

React学习记录_第17张图片

第三条路: 父子组件的生命周期顺序

React学习记录_第18张图片

 构建父子组件:

React学习记录_第19张图片

(3)总结 

React学习记录_第20张图片

2、新生命周期(17.x版本) 

React学习记录_第21张图片

如果新版本用了旧版本的钩子函数,在控制台3个带will的钩子函数,会被警告,且带上UNSAFE_钩子函数名称 :

React学习记录_第22张图片

18.x已废弃

React学习记录_第23张图片

(1)getDerivedStateFromProps

  • a. 静态方法,使用时写static
  • b. 要return 返回值,返回一个状态对象 or null

如果返回值是一个状态对象,返回状态对象就会影响状态更新componentWillUpdate,返回的状态对象含有初始状态的数据,页面渲染就按返回的状态对象来。强制更新、卸载是不受影响的。

如果向组件传入数据,组件用props接收,getDerivedStateFromProps(props),return props的效果与上面所述一致。

应用场景:state的值取决于props

(2)getSnapshotBeforeUpdate

  • 要return 返回值,返回任意数据or null。return的值给下面的生命周期钩子函数render
  • 在组件更新完毕之前进行一些需要的操作

React学习记录_第24张图片

(3)总结

React学习记录_第25张图片

十五、Diff算法

比较的最小粒度是节点

React学习记录_第26张图片

十六、初始化脚手架

脚手架基于webpack

1、安装与创建

安装脚手架:

npm i create-react-app -g

cmd打开并输入以下命令:

create-react-app 项目名称

2、文件介绍

React学习记录_第27张图片

React学习记录_第28张图片

3、模板

App.js

import './App.css';
// 创建组件App
import React from 'react';


class App extends React.Component {
  render(){
    return (
      
hello
) } } export default App;

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  // 检查App代码不合理的地方
  
    
  
);


reportWebVitals();

十七、样式的模块化

React学习记录_第29张图片

十八、组件化编码流程

React学习记录_第30张图片

十九、todolist案例

1、拆分组件

React学习记录_第31张图片

2、实现静态组件

3、动态展示数据

二十、React Ajax

React学习记录_第32张图片

1、配置代理:

package.json:

“proxy”:“http://localhost:5000”    5000是服务器的端口号

2、配置多个代理

二十一、GitHub搜索案例

二十二、兄弟组件/任意组件通信——消息发布与订阅

工具库:PubSubJS

安装:

npm i pubsub-js

使用:

在componentDidMount里写

二十三、fetch发送请求

浏览器window上内置,promise封装

React学习记录_第33张图片

二十四、SPA单页面应用

React学习记录_第34张图片

二十五、React路由  React-Router

1、简介

React学习记录_第35张图片

React学习记录_第36张图片

2、版本

有3个:web,native,any

React学习记录_第37张图片

3、版本5

BrowserRouter与HashRouter的区别

React学习记录_第38张图片

4、版本6

安装命令:

npm i react-router-dom

(1)简介 + 与版本5的区别 

React学习记录_第39张图片

(2)组件使用

1)src / index.js引入路由:

import { BrowserRouter } from 'react-router-dom';

2)将a标签改为路由标签,将a里的herf属性改为to属性

Link:无高亮

NavLink:有高亮

在App.js引入:

import { NavLink } from "react-router-dom";

3)在呈现组件的位置注册路由

问题:为何废弃旧版本的switch,改为新版本的routes

书写要点:

①要用包裹起来 

②组件名称写在element属性 

③组件写成标签形式 

React学习记录_第40张图片

④一个路由匹配之后,就算path一样,也不会再匹配其他路由

⑤重定向:Navigator 只要渲染,就会引起视图的变化,默认路由跳转模式是push,replace需要打开replace={true}

⑥自定义类名:写成函数形式,可以通过类名改变导航高亮的样式

React学习记录_第41张图片

⑦useRoutes:将多个路由写成一个路由表

 React学习记录_第42张图片

 

 一般业务开发,路由配置单独写在routes/index.js:

在App.js使用:

React学习记录_第43张图片

 

⑧嵌套路由

React学习记录_第44张图片

⑨路由占位符

相当于Vue-router里的view-router

 

10)hooks

<1>useRoutes

<2>useNavigator

编程式路由导航,返回一个函数

React学习记录_第45张图片

<3>useParams 

接收当前匹配路由的params参数,直接解构就可以直接使用

React学习记录_第46张图片

<4>useSearchParams

读取和修改当前位置的url中的查询字符串

返回一个数组:[当前的search参数,更新的search参数]  《==》 [search, setSearch]

search:search参数对象,获取某个参数 =》search.get(参数名)

setSearch:更新search参数的方法

React学习记录_第47张图片

<5>useLocation

获取当前location信息

React学习记录_第48张图片

<6>useMatch

返回当前匹配信息

React学习记录_第49张图片

<7>useInRouterContext

返回是布尔值,只要是App的子组件,不管是不是路由组件,该hook的输出都是true,说明处于上下文环境中

某个组件脱离路由器的管理,就会返回false

React学习记录_第50张图片

<8>useNavigationType

通过哪种路由方式来到当前组件

返回值:pop(通过刷新页面而来),push,replace

<9>useOutlet

呈现当前组件中渲染的嵌套路由组件

<10>useResolvedPath(URL)

给定URL,解析其中的path、search、hash

编程式路由导航

React学习记录_第51张图片

二十六、Ant Design组件库

1、安装

npm i antd --save

2、引入

// 按需引入组件
import {Button} from "antd";
// 引入antd的样式
import "antd/dist/reset.css";

引入ant.css出现错误可以尝试引入ant.min.css

3、按需引入

配置具体的修改规则,config-overrides.js

4、自定义主题

安装less:npm i less less-loader

二十七、redux

1、简介

React学习记录_第52张图片

2、何时使用

 React学习记录_第53张图片

3、工作流程

React学习记录_第54张图片

react组件要进行行为时,创建一个动作对象action,action存储数据类型type和具体数据data,告诉action actors,action actors派发dispatch给store,store是一个调度者指挥者,并不对数据进行改动,store将当前数据状态和action对象发给reducers,reducers本身可以初始化状态state,此时previousState=understand,reducers把action数据对象进行加工更改后返回新的数据状态给store,store再把新的数据返回给react组件,组件通过getState获取

4、三个核心

React学习记录_第55张图片React学习记录_第56张图片

5、API

(1)createStore():创建store  已弃用

新版本 =》import { legacy_createStore as createStore } from 'redux';

(2)store.getState():获取状态

(3)store.dispatch():派发action数据对象

(4)store.subscribe(()=>{}):检测redux数据变化,数据变化就调用render

6、action

(1)同步:object一般对象类型的action

(2)异步:函数类型的action,return也是函数

React学习记录_第57张图片

7、react-redux

react插件库 

React学习记录_第58张图片

React学习记录_第59张图片优化—

优化:

React学习记录_第60张图片

开发者工具 

React学习记录_第61张图片

二十八、项目打包 

二十九、扩展

1、setState

react状态更新是异步的

React学习记录_第62张图片

2、lazyload

React学习记录_第63张图片

lazy本身是一个函数,在内部还要调用一个函数

3、hook

(1)statehook ==》 React.useState()

返回值,数组,[状态,更新状态的方法]

React学习记录_第64张图片

(2)effecthook

React学习记录_第65张图片

(3)refhook

 

4、fragment

5、 context

React学习记录_第66张图片

 React学习记录_第67张图片

6、PureComponent

React学习记录_第68张图片

7、render props

React学习记录_第69张图片

8、ErrorBoundary   错误边界

React学习记录_第70张图片

9、 组件通信方式

React学习记录_第71张图片

你可能感兴趣的:(前端,react.js,react,native,react)