react框架学习

React简介

前期知识

1.js的基础

2.es6的基础

官网

  1. 英文官网: https://reactjs.org/
  2. 中文官网: https://react.docschina.org/

介绍描述

  1. 用于动态构建用户界面的 JavaScript (只关注于视图)
  2. Facebook开源

React的特点

  1. 声明式编码(不需要操作dom 数据驱动视图只需要更新数据即可,不是不操作,在渲染的时候不可避免的需要dom)
  2. 组件化编码
  3. React Native 编写原生应用
  4. 高效(优秀的Diffing算法)
  5. 一次学习,随处编写(支持客户端 和 服务端渲染)

React高效的原因

  1. 使用虚拟(virtual)DOM, 不总是直接操作页面真实DOM
  2. DOM Diffing算法, 最小化页面重绘。

React的基本使用

相关js

  1. react.jsReact核心库。
  2. react-dom.js:提供操作DOMreact扩展库。
  3. babel.min.js:解析JSX语法代码转为JS代码的库。

创建虚拟DOM的两种方法

  1. JS方式(一般不用)
  2. JSX方式

虚拟DOM与真实DOM

  1. React提供了一些API来创建一种 “特别” 的一般js对象
      1. const VDOM = React.createElement('xx',{id:'xx'},'xx')
      2. 上面创建的就是一个简单的虚拟DOM对象
  2. 虚拟DOM对象最终都会被React转换为真实的DOM
  3. 我们编码时基本只需要操作react的虚拟DOM相关数据, react会转换为真实DOM变化而更新界。
  4. 渲染虚拟dom

    • 语法 ReactDOM.render(h1, document.getElementById('id'))

    • 作用 将虚拟dom元素渲染到页面中的真实容器中去

    • 参数说明:

      • 参数一 纯js 或者 jsx创建的虚拟dom对象

      • 参数二 用来包含虚拟dom 元素的真实dom元素对象 (一般是一个div)

      • 如图:

React JSX

JSX

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

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

模块

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

组件

  1. 理解:用来实现局部功能效果的代码和资源的集合(html/css/js/image等等)就是html css js 代码的集合
  2. 为什么要用组件: 一个界面的功能更复杂
  3. 作用:复用编码, 简化项目编码, 提高运行效率,把业务中相同的功能抽取成组件 可以让我们的代码更加简洁 复用性更高 达到代码复用的效果
  4. 自定义组件的两种方式

    1. 工厂函数组件

    2. es6类组件

  5. 组件编写注意点
    • 只能有一个根节点

    • 首字母一定要大写

    • 一定要有闭合的标签

模块化

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

组件化

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

类式组件转化为函数组件:
        

1、函数组件
数组件接收一个单一的 props 对象并返回了一个React元素
2、类组件
无论是使用函数或是类来声明一个组件,它决不能修改它自己的 props。
所有 React 组件都必须是纯函数,并禁止修改其自身 props 。
React是单项数据流,父组件改变了属性,那么子组件视图会更新。
属性 props 是外界传递过来的,状态 state 是组件本身的,状态可以在组件中任意修改
组件的属性和状态改变都会更新视图。
3、两者区别
函数组件的性能比类组件的性能要高,因为类组件使用的时候要实例化,而函数组件直接执行函数取返回结果即可。为了提高性能,尽量使用函数组件。

函数式组件:

将class 类定义的React 元素转换成 变量或者函数
class 中的 render 函数 直接去掉,直接return html 元素
将 state 变量使用 useState Hooks 替代
componentDidMount 生命周期使用 useEffect Hooks 替代
componentDidUpdate 生命周期使用 useEffect Hooks 替代
React memo 替代 PureComponent

区别:
性能上的差异较小,取决于代码是怎么写的;
class 和 闭包的区别;
函数思想还是面向对象思想;
需要做到逻辑清晰,低耦合,命名规范;
Hooks 会让代码结构更简单;
Hooks 在每次渲染或者更新都会创建一个函数执行上下文,可以使用 useCallback、useMemo;
Hooks 添加的原因,以及后续对 Hooks 的优化等可以看出 Hooks 肯定是有优于 class 的地方的;
函数组件中不能监听组件的生命周期,useEffect聚合了多个生命周期函数
class组件中生命周期较为复杂
class组件逻辑难以复用(HOC,render props)
函数组件业务代码更加聚合,比如在class 组件中定时器的创建和销毁分别在两个不同的生命周期,但 函数组件只需写在 useEffect 中即可。

性能对比:
差异较小,控制变量法。

函数组件转化为类式组件:

  • 创建一个继承自 React.Component 类的 ES6 class 同名类。
  • 添加一个名为 render() 的空方法。
  • 原函数中的所有内容移至 render() 中。
  • 在 render() 方法中使用 this.props 替代 props。
  • 删除保留的空函数声明。

类式组件:

2章:React面向组件编程

2.1. 基本理解和使用

2.1.1. 使用React开发者工具调试

2.1.2. 

函数式组件:

类式组件:

2.1.3. 注意

  1. 组件名必须首字母大写
  2. 虚拟DOM元素只能有一个根元素
  3. 虚拟DOM元素必须有结束标签

2.1.4. 渲染类组件标签的基本流程

  1. React内部会创建组件实例对象
  2. 调用render()得到虚拟DOM, 并解析为真实DOM
  3. 插入到指定的页面元素内部

2.2. 组件三大核心属性1: state

2.2.1.父子(兄弟)组件传值过程:
Father父组件传一个函数
Funuction1Son ,让Son子组件可以在自己的组件内,调用父组件的函数 Funuction

Father在自己的组件内调用父组件传来的函数Funuction1,并传值给父组件的Funuction1函数 Funuction2() { this.props.Funuction1('子组件给父组件传的值') }。

Father父组件通过Funuction1接收Son子组件传的值,setState后,

将值通过Funuction2传给Son 子组件,

子组件通过this.props.Funuction2即可获得来自 Father父组件传来的值。
 

2.2.2. 理解

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

2.2.3. 强烈注意

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

2.3. 组件三大核心属性2: props

2.3.1. 

2.3.2. 理解

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

2.3.3. 作用

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

2.3.4. 编码操作

  1. 内部读取某个属性值
  1. props中的属性值进行类型限制和必要性限制

第一种方式(React v15.5 开始已弃用):

第二种方式(新):使用prop-types库进限制(需要引入prop-types库)

  1. 扩展属性: 将对象的所有属性通过props传递
  1. 默认属性值:
  1. 组件类的构造函数             
    1. 请区分一下组件的props 和 state属性
    2. state 组件自身的内部可以变化的数据
    3. props 是组件外部向组件内部传递的数据 组件内部只读 不改变

2.4. 组件三大核心属性3: refs与事件处理

2.4.1. 

2.4.2. 理解

组件内的标签可以定义ref属性来标识自己

2.4.3. 编码

  1. 字符串形式的ref
  1. 回调形式的ref
  1. createRef创建ref容器·

2.4.4. 事件处理

  1. 通过onXxx属性指定事件处理函数(注意大小写)
    1. React使用的是自定义(合成)事件, 而不是使用的原生DOM事件
    2. React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)
  2. 通过event.target得到发生事件的DOM元素对象

2.5. 收集表单数据

2.5.1. 子组件传递数据给父组件:

        父得传给子一个函数(通过props传递)

在子需要传递数据给父时,只需要调用这个函数

2.5.2. 理解

包含表单的组件分类

    1. 受控组件
    2. 非受控组件

2.6. 组件的生命周期

2.6.1

2.6.2. 理解

  1. 组件从创建到死亡它会经历一些特定的阶段。
  2. React组件中包含一系列勾子函数(生命周期回调函数), 会在特定的时刻调用。
  3. 我们在定义组件时,会在特定的生命周期回调函数中,做特定的工作。

2.6.3. 生命周期流程图()

生命周期的三个阶段(旧):

1. 初始化阶段: ReactDOM.render()触发---初次渲染

        1. constructor()
        2. componentWillMount()
        3. render()
        4. componentDidMount()

2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发

  1. shouldComponentUpdate()
  2. componentWillUpdate()
  3. render()
  4. componentDidUpdate()

3. 卸载组件: ReactDOM.unmountComponentAtNode()触发

  1. componentWillUnmount()

2.6.4. 生命周期流程图()

生命周期的三个阶段(新):

1. 初始化阶段: ReactDOM.render()触发---初次渲染

  1. constructor()
  2. getDerivedStateFromProps
  3. render()
  4. componentDidMount()

2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发

  1. getDerivedStateFromProps
  2. shouldComponentUpdate()
  3. render()
  4. getSnapshotBeforeUpdate
  5. componentDidUpdate()

3. 卸载组件: ReactDOM.unmountComponentAtNode()触发

  1. componentWillUnmount()

2.6.5. 重要的勾子

  1. render:初始化渲染或更新渲染调用
  2. componentDidMount:开启监听, 发送ajax请求
  3. componentWillUnmount:做一些收尾工作, : 清理定时器

2.6.6. 即将废弃的勾子

  1. componentWillMount
  2. componentWillReceiveProps
  3. componentWillUpdate

现在使用会出现警告,下一个大版本需要加上UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用。

2.7. 虚拟DOMDOM Diffing算法

2.7.1. 

2.7.2. 基本原理图

3章:React应用(基于React脚手架)

3.1. 使用create-react-app创建react应用

 3.1.1构建react脚手架项目()安装:npm i create-react-app

        创建工程项目:在目录下cmd进入命令窗口create-react-app+项目名称进行项目创建(项目名称得遵循“小写字母,数字,_”命名)

        组件化,模块化()

有利于团队开发, 有利于组件的复用,方便后期的维护,减少页面代码

        如何划分组件

普通组件(没有复用性,普通拆解)

业务组件(复用性高,针对项目需求)

功能组件(多个项目,例如:UI组件库里的组件)

因为组件化开发必然会带来工程化的处理,

  1. xxx脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目
    1. 包含了所有需要的配置(语法检查、jsx编译、devServer
    2. 下载好了所有相关的依赖
    3. 可以直接运行一个简单效果
  2. react提供了一个用于创建react项目的脚手架库: create-react-app
  3. 项目的整体技术架构为:  react + webpack + es6 + eslint
  4. 使用脚手架开发的项目的特点: 模块化, 组件化, 工程化

3.1.1.1 react脚手架解读:

3.1.2. 创建项目并启动

第一步,全局安装:npm i -g create-react-app

第二步,切换到想创项目的目录,使用命令:create-react-app 项目名称

第三步,进入项目文件夹:cd 项目名称

第四步,启动项目:npm start

错误案例

1.npm WARN deprecated tar@2.2.2: This version of tar is no longer supported, and will not receive security updates. Please upgrade asap.

                分析:tar版本过低,需要升级tar版本。

                解决:

                1.执行如下命令:

                npm install -g tar

                2.首先确认Node >= 14.0.0 and npm >= 5.6 先看node和npm的版本

                

                3.执行如下命令

                npx create-react-app create-react-app(

               npm install -g create-react-app
                create-react-app my-app

                等价于

                npx create-react-app my-app 这条命令会临时安装 create-react-app 包,命令完成后create-react-app 会删掉,不会出现在 global 中。下次再执行,还是会重新临时安装

) 

3.1.3. react脚手架项目结构

public ---- 静态资源文件夹

favicon.icon ------ 网站页签图标

index.html -------- 主页面

logo192.png ------- logo图

logo512.png ------- logo图

manifest.json ----- 应用加壳的配置文件

robots.txt -------- 爬虫协议文件

src ---- 源码文件夹

App.css -------- App组件的样式

App.js --------- App组件

App.test.js ---- 用于给App做测试

index.css ------ 样式

index.js ------- 入口文件

logo.svg ------- logo图

reportWebVitals.js

--- 页面性能分析文件(需要web-vitals库的支持)

setupTests.js

---- 组件单元测试的文件(需要jest-dom库的支持)

3.1.4. 功能界面的组件化编码流程(通用)

1. 拆分组件: 拆分界面,抽取组件

2. 实现静态组件: 使用组件实现静态页面效果

3. 实现动态组件

3.1 动态显示初始化数据

3.1.1 数据类型

3.1.2 数据名称

3.1.2 保存在哪个组件?

3.2 交互(从绑定事件监听开始)

3.1.5、项目初始化

当然,我们在后续的使用时,并不需要这些东西,所以要把src目录下面的index.js留下,其他的全部删掉,并新建一个App.jsx

3.2. 组件的组合使用-TodoList

4章:React ajax

4.1. 理解

4.1.1. 前置说明

  1. React本身只关注于界面, 并不包含发送ajax请求的代码
  2. 前端应用需要通过ajax请求与后台进行交互(json数据)
  3. react应用中需要集成第三方ajax(或自己封装)

4.1.2. 常用的ajax请求库

  1. jQuery: 比较重, 如果需要另外引入不建议使用
  2. axios: 轻量级, 建议使用
      1. 安装axios

        npm install axios

        $ bower install axios

      2. 封装XmlHttpRequest对象的ajax
      3.  promise风格
      4. 可以用在浏览器端和node服务器端

4.2. axios

4.2.1. 文档

https://github.com/axios/axios

4.2.2. 相关API

GET请求

axios.get('/user?ID=12345')

  .then(function (response) {

    console.log(response.data);

  })

  .catch(function (error) {

    console.log(error);

  });

axios.get('/user', {

    params: {

      ID: 12345

    }

  })

  .then(function (response) {

    console.log(response);

  })

  .catch(function (error) {

    console.log(error);

  });

POST请求

axios.post('/user', {

  firstName: 'Fred',

  lastName: 'Flintstone'

})

.then(function (response) {

console.log(response);

})

.catch(function (error) {

console.log(error);

});

4.3. 案例—github用户搜索

4.3.1. 

请求地址: https://api.github.com/search/users?q=xxxxxx

4.4. 消息订阅-发布机制

  1. 工具库: PubSubJS
  2. 下载: npm install pubsub-js --save
  3. 使用:
        1. import PubSub from 'pubsub-js' //引入
        2. PubSub.subscribe('delete', function(data){ }); //订阅
        3. PubSub.publish('delete', data) //发布消息

4.5. 扩展:Fetch

4.5.1. 文档

  1. https://github.github.io/fetch/
  2. 滑动验证页面

4.5.2. 特点

  1. fetch: 原生函数,不再使用XmlHttpRequest对象提交ajax请求
  2. 老版本浏览器可能不支持

4.5.3. 相关API

  1. GET请求

fetch(url).then(function(response) {

    return response.json()

  }).then(function(data) {

    console.log(data)

  }).catch(function(e) {

    console.log(e)

  });

  1. POST请求

  fetch(url, {

    method"POST",

    bodyJSON.stringify(data),

  }).then(function(data) {

    console.log(data)

  }).catch(function(e) {

    console.log(e)

  })

5章:React路由

5.1. 相关理解

5.1.1. SPA的理解

  1. 单页Web应用(single page web applicationSPA)。
  2. 整个应用只有一个完整的页面
  3. 点击页面中的链接不会刷新页面,只会做页面的局部更新。
  4. 数据都需要通过ajax请求获取, 并在前端异步展现。

5.1.2. 路由的理解

  1. 什么是路由?
    1. 一个路由就是一个映射关系(key:value)
    2. key为路径, value可能是function或component
  2. 路由分类
    1. 后端路由:
      1. 理解: valuefunction, 用来处理客户端提交的请求。
      2. 注册路由: router.get(path, function(req, res))
      3. 工作过程:当node接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据
    2. 前端路由:
      1. 浏览器端路由,valuecomponent,用于展示页面内容。
      2. 注册路由: <Route path="/test" component={Test}>
      3. 工作过程:当浏览器的path变为/test, 当前路由组件就会变为Test组件

5.1.3. react-router-dom的理解

  1. react的一个插件库。
  2. 专门用来实现一个SPA应用。
  3. 基于react的项目基本都会用到此库。

5.2. react-router-dom相关API

5.2.1. 内置组件

  1. <BrowserRouter>
  2. <HashRouter>
  3. <Route>
  4. <Redirect>
  5. <Link>
  6. <NavLink>
  7. <Switch>

5.2.2. 其它

  1. history对象
  2. match对象
  3. withRouter函数

5.3. 基本路由使用

5.3.1.React Router 6 快速上手

5.3.1.1概述
  1. React Router 以三个不同的包发布到 npm 上,它们分别为:

    1. react-router: 路由的核心库,提供了很多的:组件、钩子。

    2. react-router-dom: 包含react-router所有内容,并添加一些专门用于 DOM 的组件,例如 <BrowserRouter>等 

    3. react-router-native: 包括react-router所有内容,并添加一些专门用于ReactNative的API,例如:<NativeRouter>等。

  2. 与React Router 5.x 版本相比,改变了什么?

    1. 内置组件的变化:移除<Switch/> ,新增 <Routes/>等。

    2. 语法的变化:component={About} 变为 element={<About/>}等。

    3. 新增多个hook:useParamsuseNavigateuseMatch等。

    4. 官方明确推荐函数式组件了!!!

      ......

5.3.1.2.Component
1. <BrowserRouter>
  1. 说明:<BrowserRouter>用于包裹整个应用。

  2. 示例代码:

    import React from "react";
    import ReactDOM from "react-dom";
    import { BrowserRouter } from "react-router-dom";
    ​
    ReactDOM.render(
      <BrowserRouter>
        {/* 整体结构(通常为App组件) */}
      </BrowserRouter>,root
    );
2. <HashRouter>
  1. 说明:作用与<BrowserRouter>一样,但<HashRouter>修改的是地址栏的hash值。

  2. 备注:6.x版本中<HashRouter><BrowserRouter> 的用法与 5.x 相同。

3. <Routes/> 与 <Route/>
  1. v6版本中移出了先前的<Switch>,引入了新的替代者:<Routes>

  2. <Routes><Route>要配合使用,且必须要用<Routes>包裹<Route>

  3. <Route> 相当于一个 if 语句,如果其路径与当前 URL 匹配,则呈现其对应的组件。

  4. <Route caseSensitive> 属性用于指定:匹配时是否区分大小写(默认为 false)。

  5. 当URL发生变化时,<Routes>都会查看其所有子<Route> 元素以找到最佳匹配并呈现组件 。

  6. <Route> 也可以嵌套使用,且可配合useRoutes()配置 “路由表” ,但需要通过 <Outlet> 组件来渲染其子路由。

  7. 示例代码:

    <Routes>
        /*path属性用于定义路径,element属性用于定义当前路径所对应的组件*/
        <Route path="/login" element={<Login />}></Route>
    ​
            /*用于定义嵌套路由,home是一级路由,对应的路径/home*/
        <Route path="home" element={<Home />}>
           /*test1 和 test2 是二级路由,对应的路径是/home/test1 或 /home/test2*/
          <Route path="test1" element={<Test/>}></Route>
          <Route path="test2" element={<Test2/>}></Route>
            </Route>
        
            //Route也可以不写element属性, 这时就是用于展示嵌套的路由 .所对应的路径是/users/xxx
        <Route path="users">
           <Route path="xxx" element={<Demo />} />
        </Route>
    </Routes>
4. <Link>
  1. 作用: 修改URL,且不发送网络请求(路由链接)。

  2. 注意: 外侧需要用<BrowserRouter><HashRouter>包裹。

  3. 示例代码:

    import { Link } from "react-router-dom";
    ​
    function Test() {
      return (
        <div>
            <Link to="/路径">按钮</Link>
        </div>
      );
    }
5. <NavLink>
  1. 作用: 与<Link>组件类似,且可实现导航的“高亮”效果。

  2. 示例代码:

    // 注意: NavLink默认类名是active,下面是指定自定义的class
    ​
    //自定义样式
    <NavLink
        to="login"
        className={({ isActive }) => {
            console.log('home', isActive)
            return isActive ? 'base one' : 'base'
        }}
    >login</NavLink>
    ​
    /*
        默认情况下,当Home的子组件匹配成功,Home的导航也会高亮,
        当NavLink上添加了end属性后,若Home的子组件匹配成功,则Home的导航没有高亮效果。
    */
    <NavLink to="home" end >home</NavLink>
6. <Navigate>
  1. 作用:只要<Navigate>组件被渲染,就会修改路径,切换视图。

  2. replace属性用于控制跳转模式(push 或 replace,默认是push)。

  3. 示例代码:

    import React,{useState} from 'react'
    import {Navigate} from 'react-router-dom'
    ​
    export default function Home() {
        const [sum,setSum] = useState(1)
        return (
            <div>
                <h3>我是Home的内容</h3>
                {/* 根据sum的值决定是否切换视图 */}
                {sum === 1 ? <h4>sum的值为{sum}</h4> : <Navigate to="/about" replace={true}/>}
                <button onClick={()=>setSum(2)}>点我将sum变为2</button>
            </div>
        )
    }
7. <Outlet>
  1. <Route>产生嵌套时,渲染其对应的后续子路由。

  2. 示例代码:

    //根据路由表生成对应的路由规则
    const element = useRoutes([
      {
       path:'/about',
       element:<About/>
      },
      {
       path:'/home',
       element:<Home/>,
       children:[
         {
           path:'news',
           element:<News/>
         },
         {
           path:'message',
           element:<Message/>,
         }
       ]
      }
    ])

    //Home.js
    import React from 'react'
    import {NavLink,Outlet} from 'react-router-dom'

    export default function Home() {
        return (
            <div>
                <h2>Home组件内容</h2>
                <div>
                    <ul className="nav nav-tabs">
                        <li>
                            <NavLink className="list-group-item" to="news">News</NavLink>
                        </li>
                        <li>
                            <NavLink className="list-group-item" to="message">Message</NavLink>
                        </li>
                    </ul>
                    {/* 指定路由组件呈现的位置 */}
                    <Outlet />
                </div>
            </div>
        )
    }

5.3.1.3.Hooks

1. useRoutes()
  1. 作用:根据路由表,动态创建<Routes><Route>

  2. 示例代码:

    //路由表配置:src/routes/index.js
    import About from '../pages/About'
    import Home from '../pages/Home'
    import {Navigate} from 'react-router-dom'
    ​
    export default [
        {
            path:'/about',
            element:<About/>
        },
        {
            path:'/home',
            element:<Home/>
        },
        {
            path:'/',
            element:<Navigate to="/about"/>
        }
    ]
    ​
    //App.jsx
    import React from 'react'
    import {NavLink,useRoutes} from 'react-router-dom'
    import routes from './routes'
    ​
    export default function App() {
        //根据路由表生成对应的路由规则
        const element = useRoutes(routes)
        return (
            <div>
                ......
          {/* 注册路由 */}
          {element}
              ......
            </div>
        )
    }
    ​
2. useNavigate()
  1. 作用:返回一个函数用来实现编程式导航。

  2. 示例代码:

    import React from 'react'
    import {useNavigate} from 'react-router-dom'
    ​
    export default function Demo() {
      const navigate = useNavigate()
      const handle = () => {
        //第一种使用方式:指定具体的路径
        navigate('/login', {
          replace: false,
          state: {a:1, b:2}
        }) 
        //第二种使用方式:传入数值进行前进或后退,类似于5.x中的 history.go()方法
        navigate(-1)
      }
      
      return (
        <div>
          <button onClick={handle}>按钮</button>
        </div>
      )
    }
3. useParams()
  1. 作用:回当前匹配路由的params参数,类似于5.x中的match.params

  2. 示例代码:

    import React from 'react';
    import { Routes, Route, useParams } from 'react-router-dom';
    import User from './pages/User.jsx'
    ​
    function ProfilePage() {
      // 获取URL中携带过来的params参数
      let { id } = useParams();
    }
    ​
    function App() {
      return (
        <Routes>
          <Route path="users/:id" element={<User />}/>
        </Routes>
      );
    }
4. useSearchParams()
  1. 作用:用于读取和修改当前位置的 URL 中的查询字符串。

  2. 返回一个包含两个值的数组,内容分别为:当前的seaech参数、更新search的函数。

  3. 示例代码:

    import React from 'react'
    import {useSearchParams} from 'react-router-dom'
    ​
    export default function Detail() {
        const [search,setSearch] = useSearchParams()
        const id = search.get('id')
        const title = search.get('title')
        const content = search.get('content')
        return (
            <ul>
                <li>
                    <button onClick={()=>setSearch('id=008&title=哈哈&content=嘻嘻')}>点我更新一下收到的search参数</button>
                </li>
                <li>消息编号:{id}</li>
                <li>消息标题:{title}</li>
                <li>消息内容:{content}</li>
            </ul>
        )
    }
    ​
5. useLocation()
  1. 作用:获取当前 location 信息,对标5.x中的路由组件的location属性。

  2. 示例代码:

    import React from 'react'
    import {useLocation} from 'react-router-dom'
    ​
    export default function Detail() {
        const x = useLocation()
        console.log('@',x)
      // x就是location对象: 
        /*
            {
          hash: "",
          key: "ah9nv6sz",
          pathname: "/login",
          search: "?name=zs&age=18",
          state: {a: 1, b: 2}
        }
        */
        return (
            <ul>
                <li>消息编号:{id}</li>
                <li>消息标题:{title}</li>
                <li>消息内容:{content}</li>
            </ul>
        )
    }
    ​
      
    ​
    ​
6. useMatch()
  1. 作用:返回当前匹配信息,对标5.x中的路由组件的match属性。

  2. 示例代码:

    <Route path="/login/:page/:pageSize" element={<Login />}/>
    <NavLink to="/login/1/10">登录</NavLink>
    
    export default function Login() {
      const match = useMatch('/login/:x/:y')
      console.log(match) //输出match对象
      //match对象内容如下:
      /*
      	{
          params: {x: '1', y: '10'}
          pathname: "/LoGin/1/10"  
          pathnameBase: "/LoGin/1/10"
          pattern: {
          	path: '/login/:x/:y', 
          	caseSensitive: false, 
          	end: false
          }
        }
      */
      return (
      	<div>
          <h1>Login</h1>
        </div>
      )
    }
7. useInRouterContext()

作用:如果组件在 <Router> 的上下文中呈现,则 useInRouterContext 钩子返回 true,否则返回 false。

8. useNavigationType()
  1. 作用:返回当前的导航类型(用户是如何来到当前页面的)。

  2. 返回值:POPPUSHREPLACE

  3. 备注:POP是指在浏览器中直接打开了这个路由组件(刷新页面)。

9. useOutlet()
  1. 作用:用来呈现当前组件中渲染的嵌套路由。

  2. 示例代码:

    const result = useOutlet()
    console.log(result)
    // 如果嵌套路由没有挂载,则result为null
    // 如果嵌套路由已经挂载,则展示嵌套的路由对象
10.useResolvedPath()
  1. 作用:给定一个 URL值,解析其中的:path、search、hash值。

5.3.2. 准备
  1. 下载react-router-dom: npm install --save react-router-dom
  2. 引入bootstrap.css: <link rel="stylesheet" href="/css/bootstrap.css">

5.4. 嵌套路由使用

5.5. 向路由组件传递参数数据

5.6. 多种路由跳转方式

6章:React UI组件库

6.1.流行的开源React UI组件库

6.1.1. material-ui(国外)

  1. 官网: http://www.material-ui.com/#/
  2. github: https://github.com/callemall/material-ui

6.1.2. ant-design(国内蚂蚁金服)

  1. 官网: Ant Design - 一套企业级 UI 设计语言和 React 组件库
  2. Github: https://github.com/ant-design/ant-design/

7章:redux

7.1. redux理解

7.1.1. 学习文档

  1. 英文文档: Redux - A predictable state container for JavaScript apps. | Redux
  2. 中文文档: Redux 中文文档 · Redux
  3. Github: https://github.com/reactjs/redux

7.1.2. redux是什么

  1. redux是一个专门用于做状态管理JS(不是react插件库)
  2. 它可以用在react, angular, vue等项目中, 但基本与react配合使用。
  3. 作用: 集中式管理react应用中多个组件共享的状态。

7.1.3. 什么情况下需要使用redux

  1. 某个组件的状态,需要让其他组件可以随时拿到(共享)。
  2. 一个组件需要改变另一个组件的状态(通信)。
  3. 总体原则:能不用就不用, 如果不用比较吃力才考虑使用。

7.1.4. redux工作流程

7.2. redux的三个核心概念

7.2.1. action

  1. 动作的对象
  2. 包含2个属性
    1. type:标识属性, 值为字符串, 唯一, 必要属性
    2. data:数据属性, 值类型任意, 可选属性
  3. 例子:{ type: 'ADD_STUDENT',data:{name: 'tom',age:18} }

7.2.2. reducer

  1. 用于初始化状态、加工状态。
  2. 加工时,根据旧的stateaction 产生新的state纯函数

7.2.3. store

  1. stateactionreducer联系在一起的对象
  2. 如何得到此对象?
            1. import {createStore} from 'redux'
            2. import reducer from './reducers'
            3. const store = createStore(reducer)
  3. 此对象的功能?
            1. getState(): 得到state
            2. dispatch(action): 分发action, 触发reducer调用, 产生新的state
            3. subscribe(listener): 注册监听, 当产生了新的state时, 自动调用

7.3. redux的核心API

7.3.1. createstore()

作用:创建包含指定reducer的store对象

7.3.2. store对象

  1. 作用: redux库最核心的管理对象
  2. 它内部维护着:
          1. state
          2. reducer
  3. 核心方法:
          1. getState()
          2. dispatch(action)
          3. subscribe(listener)
  4. 具体编码:
          1. store.getState()
          2. store.dispatch({type:'INCREMENT', number})
          3. store.subscribe(render)

7.3.3. applyMiddleware()

作用:应用上基于redux的中间件(插件库)

7.3.4. combineReducers()

作用:合并多个reducer函数

7.4. 使用redux编写应用

  

7.5. redux异步编程

7.5.1理解:

  1. redux默认是不能进行异步处理的,
  2. 某些时候应用中需要在redux中执行异步任务(ajax, 定时器)

7.5.2. 使用异步中间件

npm install --save redux-thunk

7.6. react-redux

7.6.1. 理解

  1. 一个react插件库
  2. 专门用来简化react应用中使用redux

7.6.2. react-Redux将所有组件分成两大类

  1. UI组件
      1. 只负责 UI 的呈现,不带有任何业务逻辑
      2. 通过props接收数据(一般数据和函数)
      3. 不使用任何 Redux  API
      4. 一般保存在components文件夹下
  2. 容器组件
      1. 负责管理数据和业务逻辑,不负责UI的呈现
      2. 使用 Redux  API
      3. 一般保存在containers文件夹下

7.6.3. 相关API

  1. Provider:让所有组件都可以得到state数据
  1. connect:用于包装 UI 组件生成容器组件
  1. mapStateToprops:将外部的数据(即state对象)转换为UI组件的标签属性
  1. mapDispatchToProps:将分发action的函数转换为UI组件的标签属性

7.7. 使用上redux调试工具

7.7.1. 安装chrome浏览器插件

7.7.2. 下载工具依赖包

npm install --save-dev redux-devtools-extension

7.8. 纯函数和高阶函数

7.8.1. 纯函数

  1. 一类特别的函数: 只要是同样的输入(实参),必定得到同样的输出(返回)
  2. 必须遵守以下一些约束  
      1. 不得改写参数数据
      2. 不会产生任何副作用,例如网络请求,输入和输出设备
      3. 不能调用Date.now()或者Math.random()等不纯的方法  
  3. reduxreducer函数必须是一个纯函数

7.8.2. 高阶函数

  1. 理解: 一类特别的函数
      1. 情况1: 参数是函数
      2. 情况2: 返回是函数
  1. 常见的高阶函数:
      1. 定时器设置函数
      2. 数组的forEach()/map()/filter()/reduce()/find()/bind()
      3. promise
    1. react-redux中的connect函数作用: 能实现更加动态, 更加可扩展的功能

第8章.关于外来网站扩展

8.1ant-design(国内蚂蚁金服)

  1. 8.1.1  需要先安装ant 不然不能识别

    1. 、安装antd

    2. 接下来就是安装ant-design到这个小demo中,点击这里前往ant-desgin的官网。

      我们使用yarn命令安装:

      yarn add antd

        然后根目录下创建next.config.js进行配置

const withCss = require('@zeit/next-css')

if(typeof require !== 'undefined'){
    require.extensions['.css']=file=>{}
}

module.exports = withCss({})


再安装antd

npm i --s antd

再安装babel-plugin-import

npm i --s babel-plugin-import

        3  再在根目录下创建.babelrc

{
    "presets":["next/babel"],  //Next.js的总配置文件,相当于继承了它本身的所有配置
    "plugins":[     //增加新的插件,这个插件就是让antd可以按需引入,包括CSS
        [
            "import",
            {
                "libraryName":"antd"
            }
        ]
    ]
}

然后在page中创建或修改_app.js

import App from 'next/app'

import 'antd/dist/antd.css'

export default App

接下来就可以在页面中按需引入了

 ant-design 的引入有两种方式:

    方式一: import  DatePicker from 'antd/es/date-picker'   // 加载js

         import  'ant/es/date-picker/style/css'   // 加载  css

    方式二: import { DatePicker } from 'antd'

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

k笔墨丹青

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值