小白入门react

第一章 入门

1.1 简介

  1. 是什么?

    构建用户界面的Javascript库,将数据渲染成html视图的开源js库

  2. 谁开发的?

    Facebook的 Jordan Walke开发,开源

  3. 为什么要学?

    1. 原生JS操作DOM繁琐、效率低(DOM-API操作UI)

    2. 使用JS操作DOM,浏览器会进行大量的重绘重排

    3. 原生JS没有组件化编码方案,代码复用率低。

    直白来说,模块化是拆解js代码,组件化不仅仅拆解js,还包括html/css/图片等

  4. React的特点

    1. 采用组件化模式,声明式编码,提高开发效率及组件复用率。

      • 命令式编程(Imperative):详细告诉机器怎么去处理一件事情以叨叨你想要的结果,其中一个环节出问题,一整个任务就完成不了
      • 声名式编程(Declarative):告诉机器你想要的结果,机器自己摸索过程

      更具体内容可参考https://developer.aliyun.com/article/270068

    2. React Native中可以使用react语法进行移动端开发(编写安卓、IOS应用)

    3. 使用虚拟DOM+优秀的Diffing算法,尽量减少与真实DOM的交互

1.2 基本使用

  1. 使用

    1. 准备一个容器

    2. 先引入核心库,再引入react-dom,最后引入babel

      <div id="test"></div>
      <script src="../js/react.development.js"></script>
      <script src="../js/react-dom.development.js"></script>
      <script src="../js/babel.min.js"></script>
      
    3. <script type="text/babel"> //一定要写babel
              // 创建虚拟DOM
              const VDOM = <h1>Hello React</h1> 
      		//此处不要写引号,因为不是字符串
              // 渲染虚拟dom到页面
              ReactDOM.render(VDOM,document.getElementById('test'))
      </script>
      

    虚拟dom的创建为什么使用jsx,不使用js?

    使开发人员方便创建虚拟dom,其实就是原生js创建虚拟dom的语法糖

  2. 虚拟DOM

    1. 虚拟DOM是什么?
      • 本质是一个一般对象
      • 虚拟dom比较“轻”,真实dom比较“重”,因为虚拟dom是在react内部用,无需真实dom上那么多特性
      • 虚拟DOM最终会被React转化为真实dom,呈现在页面上
  3. JSX

jsx语法规则:

  • 定义虚拟dom时,不要写引号

  • 标签中混入js表达式时要用{}

    表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方

    • a
    • a+b
    • demo(1)
    • arr.map()
    • function test(){}

    js语句/代码:

    • if(){}
    • for(){}
    • switch(){case:xxx}
  • 样式的类名指定不要用class,要用className

  • 内联样式,要用style={{key:value}}的形式去写

  • 只能有一个根标签

  • 标签必须闭合

  • 标签首字母

    • 小写字母开头,则将该标签转为html中同名元素,若html无该标签对应的同名元素,则报错
    • 大写字母开头,react就去渲染对应的组件,若组件没有定义,则报错
    <body>
        <!-- 创建一个容器 -->
        <div id="test"></div>
        <!-- 引入JS-->
        <script src="./js/react.development.js"></script>
        <script src="./js/react-dom.development.js"></script>
        <script src="./js/babel.min.js"></script>
    
        <script type="text/babel">
            const data = ['Angular','React','Vue'];
            // 创建虚拟dom
            const VDOM = (
                <div>
                    <h1>前端js框架列表</h1>
                    <ul>
                        {data.map((num,index)=>{
                            return <li key={index}>{num}</li>
                        })}
                    </ul>
                </div>           
            )
            // 渲染虚拟dom到页面 
            ReactDOM.render(VDOM,document.getElementById('test'))
        </script>
    </body>
    

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

  1. 模块

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

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

    当js应用以模块来编写

  4. 组件化

    应用以多组件的方式实现

第二章 面向组件编程

2.1 基本理解和使用

  1. 函数式组件

    <body>
        <div id="test"></div>
    
        <script src="../js/react.development.js"></script>
        <script src="../js/react-dom.development.js"></script>
        <script src="../js/babel.min.js"></script>
    
        <script type="text/babel">
            // 创建函数式组件
            function Demo(){
            	console.log(this);//此处的this是undefined,babel编译后开启了严格模式 `use strict`
                return <h2>我是用函数定义的组件(适用于简单组件)</h2>
            }
            // 渲染组件到页面
            ReactDOM.render(<Demo/>,document.getElementById('test'));
    		/*
    		执行了ReactDOM.render()之后发生了什么?
    		1. React解析组件标签,找到Demo组件
    		2. 发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DOM,随后呈现			在页面中
    		*/
        </script>
    </body>
    

    补充一下严格模式的相关知识

    1. “use strict” 不是一条语句,是一个字面量表达式
    2. 特点:
      • 不能使用未声明的变量
      • 不允许删除变量、对象、函数
      • 不允许变量重名
      • 不允许使用八进制、转义字符
      • 禁止this指向全局对象

    详细内容可参考https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode

  2. 类式组件

    1. 类的基本知识复习

      类的定义、类的继承

      总结:

      1. 类中的构造器不是必须写的,要对实例进行一些初始化操作,如添加指定属性时才写
      2. 若A类继承了B类,且A类中定义了构造器,那么A类构造器中的super方法是必须要调用的
      3. 类中所定义的方法,都是放在类的原型对象上,供实例去使用
    2. <script type="text/babel">
              // 创建类式组件
          	//extends不能漏掉!!!
              class Demo extends React.Component{
                  //render放在Demo的原型对象上
                  //render中的this指向Demo组件实例对象
                  render(){
                      return (
                          <div>
                              hello react
                          </div>
                      )
                  }
              }
              // 渲染组件到页面
      ReactDOM.render(<Demo/>,document.getElementById('test'));
      	/*
      		执行了ReactDOM.render()之后发生了什么?
      		1. React解析组件标签,找到Demo组件
      		2. 发现组件是使用类定义的,随后new该类的实例,并通过该实例调用原型上的render
      		3. 将render返回的虚拟dom转为真实dom,随后呈现在页面中。
      	*/
      </script>
      
  3. 简单组件与复杂组件

    简单–无状态,复杂–有状态

2.2 组件实例的三大核心属性1:state

组件实例对象生成state,状态存放数据,状态驱动页面

  1. 理解:

    1. state是组件对象中最重要的属性,其属性值是对象(可以包含多个key-value的组合)state={key:value}
    2. 组件被称为“状态机”,通过更新组件的state来更新对应的页面显示(重新渲染组件)
  2. 状态的改变:不可以直接更改,要借助内置API–setState({}) 更改

  3. 类中可以直接写赋值语句–相当于给类添加了一个属性

    class car {
        constructor(name,price){
            this.name=name;
            this.price=price;
        }
        //相当于给类添加了一个名为a的属性,属性值为1
        a=1;
    }
    
  4. 类式组件的简写

    <script type="text/babel">
    
        class Weather extends React.Component {
          // 初始化状态
          state = { isHot: true, wind: '微风' };
    
          render() {
            const { isHot, wind } = this.state;
            return (
              <h2 onClick={this.changeWeather}>
                今天天气很{isHot ? '炎热' : '凉爽'},{wind}
              </h2>
            )
          }
          // 自定义方法--赋值语句的形式+箭头函数
          changeWeather = () => {
            const isHot = this.state.isHot;
            this.setState({ isHot: !isHot })
          }
        }
        // 组件渲染到页面
        ReactDOM.render(<Weather />, document.getElementById('test'));
    
      </script>
    
  5. 强烈注意

    1. 组件中render方法中this指向组件实例对象
    2. 组件自定义的方法中this为undefined(作为事件函数),如何解决?
      • 强制绑定this:通过函数对象的bind()方法
      • 使用箭头函数(赋值语句形式+箭头函数)
    3. 状态数据不能直接修改或更新,要借助API—setState()

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

  1. Demo—自定义用来显示一个人员信息的组件

    1. 姓名必须指定,且为字符串类型
    2. 性别为字符串类型,若性别没有指定,默认为男
    3. 年龄必须指定,且为数字类型
    <script type="text/babel">
        class Person extends React.Component {
          // state = { name: 'tom', sex: '女', age: 18 }
          render() {
            const {name,sex,age}=this.props;
            return (
              <ul>
                <li>姓名:{name}</li>
                <li>性别:{sex}</li>
                <li>年龄:{age}</li>
              </ul>
            )
          }
        }
        ReactDOM.render(<Person name='tom' sex='女' age='18' />, document.getElementById('test1'));
        ReactDOM.render(<Person name='mike' sex='男' age='18' />, document.getElementById('test2'));
        ReactDOM.render(<Person name='lily' sex='女' age='20' />, document.getElementById('test3'));
      </script>
    
  2. 理解:

    每个组件对象都会有props属性

    组件标签的所有属性都保存在props中

  3. 作用:

    通过标签属性从组件外向组件内传递变化的数据

    组件内部不要修改props数据

  4. 对props的一些操作

    1. 对属性值进行限制

      使用prop-types库

      Person.propTypes={
        name:PropTypes.string.isRequired,
        age:PropTypes.number
      }
      
    2. 设置默认属性值

      Person.defaultProps={
        name:'TOM',
        age:18
      }
      
    3. 扩展属性:将对象的所有属性通过props传递

      <Person {...person}
      

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

  1. 理解:组件内的标签可以通过ref属性来标识自己

  2. ref编码形式

    • 字符串形式的ref

      <input ref="input1"/>
      
    • 回调形式

      <input ref={c=>this.input1=c}/>
      
    • createRef

      myRef = React.createRef()
      <input ref={this.myRef}/>
      
  3. 事件处理:

    ​ 通过onXxxx属性指定时间处理函数(注意大小写)

    1. React使用的是自定义(合成)事件,而不是使用原生DOM事件
    2. React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)
    3. 通过event.target得到发生事件的DOM元素对象

2.5 收集表单数据

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

2.6 组件生命周期

  1. 理解

    1. 组件从创建到死亡会经历一些特定的阶段
    2. react组件中包含一系列钩子函数(生命周期回调函数),会在特定时刻调用
    3. 我们在定义组件时,会在特定的生命周期回调函数中做特定工作
  2. 旧生命周期
    在这里插入图片描述

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

      • constructor()

      • componentWillMount()

      • render()

        必须使用

      • componentDidMount()

        常用,一般在这个钩子中做初始化的工作,例如开启定时器,发送网络请求,订阅消息等

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

      • componentWillReceiveProps()

      • shouldComponentUpdate()

        控制组件更新的阀门,是否允许更新,返回true则允许,返回 false则禁止

        若不写该钩子函数,默认返回true

      • componentWillUpdate()

      • render()

      • componentDidUpdate()

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

      • componentWillUnmount()

        一般做收尾的工作,例如:关闭定时器、取消订阅消息

  3. 新生命周期
    在这里插入图片描述

    1. 即将废除,尽量避免使用

      UNSAFE–不是指不安全,这些方法经常被误解或滥用

      UNSAFE_componentWillMount()

      UNSAFE_componentWillUpdate()

      UNSAFE_componentWillReceiveProps()

    2. 新生命周期

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

        • constructor()

        • getDerivedStateFromProps(props,state)

          • 使用概率低

          • 要定义成 static,必须返回一个状态对象(state object)或者null

          • 若state的值在任何时候都取决于props,可使用getDerivedFromProps(props){},

          • 派生状态会导致代码冗余,并使组件难以维护。

        • render()

          必须使用

        • componentDidMount()

          常用,一般在这个钩子中做初始化的工作,例如开启定时器,发送网络请求,订阅消息等

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

        • getDerivedStateFromProps()

        • shouldComponentUpdate()

          控制组件更新的阀门,是否允许更新,返回true则允许,返回 false则禁止

          若不写该钩子函数,默认返回true*

        • render()

        • getSnapshotBeforeUpdate()

          • 在最近一次渲染输出(提到DOM节点)之前调用。它使得组件能子啊发生更改之前从DOM中捕获一些信息(比如:滚动位置)。
          • 返回一个快照值(任何类型)或者null,返回值将作为参数传递给componentDidUpdate()
        • componentDidUpdate(preProps,preState)

          这里的状态是先前的state,props是先前的

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

        • componentWillUnmount()

          一般做收尾的工作,例如:关闭定时器、取消订阅消息

2.7 虚拟DOM与DOM Diff算法

  1. 对比的最小单位是标签

  2. key

    面试题:

    1. react/vue中的key有什么作用?
    2. 为什么遍历列表时,key最好不要用index?
    • 虚拟DOM中key的作用

      1. 简单来说,key是虚拟DOM对象的标识,在更新显示时key起着极其重要的作用

      2. 详细的说,当状态中的数据发生改变时,react会根据【新数据】生成【新的虚拟DOM】,随后react进行【新虚拟DOM】与【旧虚拟DOM】的diff比较,比较规则如下:

        • 旧虚拟DOM中找到了与新虚拟DOM相同的key:

          • 若虚拟DOM内容没变,直接使用之前真实DOM
          • 若虚拟DOM内容改变,则生成新的真实DOM,随后替换掉页面中之前的真实DOM
        • 旧虚拟DOM中未找到与新虚拟DOM相同的key:

          ​ 根据数据创建新的真实DOM,随后渲染到页面

    • 用Index作为key可能引发的问题:

      1. 若对数据进行:逆序添加、逆序删除等破坏顺序操作

        ​ 会产生没有必要的真实DOM更新 ==》 界面效果没问题,但效率低

      2. 若结构中还包含输入类的DOM

        ​ 会产生错误DOM更新 ==》 界面有问题

      3. 注意:若不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index时没有问题的。

    • 开发中如何选择key

      1. 最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值
      2. 若确定只是简单的展示数据,用Index也是可以的

第三章 React应用(基于脚手架)

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

  1. react脚手架

    1. 用来帮助程序员快速创建一个基于xxx库的模板项目
      1. 包含所有配置
      2. 下载好所有相关依赖
      3. 可直接运行一个简单效果
    2. react提供了一个用于创建react项目的脚手架库:create-react-app
    3. 整体架构:react+webpack+es6+eslint
  2. 创建项目并启动

    $ npm i -g create-react-app //全局安装
    $ create-react-app my-app //创建react项目
    或者
    $ npx create-react-app my-app
    $ cd my-app //进入项目
    $ npm/yarn start //启动项目
    $ npm/yarn build //将项目进行打包,生成静态文件,一般在应用完成
    $ npm/yarn eject //react默认将webpack配置/相关文件隐藏,将所有webpack相关配置暴露出来,一旦执行该指令,无法再隐藏起来
    
  3. 功能界面的组件化编码流程

    1. 拆分组件:拆分界面,抽取组件
    2. 实现静态组件:使用组件实现静态页面效果
    3. 实现动态组件:
      1. 动态显示初始化数据
        • 数据类型
        • 数据名称
        • 保存在哪个组件
      2. 交互–从绑定事件监听开始

第四章 react ajax

4.1 理解

  1. react只关注界面,并不包含发送ajax请求的代码

  2. jquery比较重,不建议使用

  3. axios:轻量级,建议使用

    • 封装XMLHttpRequest对象的ajax

    • promise风格

    • 可以在浏览器和node服务器端

4.2 脚手架配置代理

产生跨域的本质是–ajax引擎拦截响应

  1. 方法一:

    在package.json中配置一个代理

    "proxy":"http://localhost:5000"
    
    • 优点:配置简单,前端请求资源时可以不加任何前缀

    • 缺点:不能配置多个代理

    • 工作方式:上述方式配置代理,当请求了3000不存在的资源时,该请求会转发给5000(优先匹配前端资源)

  2. 方法二

    在src文件中创建setupProxy.js

  • 文件名是固定的,不可改变
  • 不能用ES6来写代码,用CJS来写
  • 不是作为前端代码来执行,react脚手架将它交给webpack,由webpack处理
const proxy = require('http-proxy-middleware')

module.exports = function(app){
    app.use(
        //遇见'/api1'前缀的请求,就会触发该代理配置
    	proxy('/api1',{ 
            //请求转发给谁,配置转发目标地址(能返回数据的服务器地址)
            target:'http://localhost:5000',
            //控制服务器收到的请求头中的Host字段的值
            //请求来自哪里
            //true--host:localhost:5000
            //false--hosy:localhost:3000
            //默认值为false,但一般将它设置为true
            changeOrigin:true,
            //重写请求路径,一定要加,
            //在送给服务器时去掉'/api1'
            //保证交给后台服务器是正常请求地址
            pathRewrite:{'^/api1':''}
        }),
        proxy('/api2',{
            target:'http://localhost:5001',
            changeOrigin:true,
            pathRewrite:{'^/api2':''}
        }),
    )
}
  • 优点:可配置多个代理,可灵活的控制请求是否走代理
  • 缺点:配置繁琐,前端请求资源时必须加前缀

4.3 消息订阅-发布机制

适用于任意组件通信

要在组件的componentWillUnmount中取消订阅

  1. 下载:npm i pubsub-js
  2. //导入
    import PubSub from 'pubsub-js'
    //订阅消息
    this.token=PubSub.subscribe('my-topic',callback)
    //发布消息
    PubSub.publish('my-topic',callback)
    //取消订阅
    PubSub.unsubscribe(this.token)
    

4.4 fetch

  1. 参考文档

    fetch官网

  2. why fetch

    XMLHttpRequest是一个设计粗糙的API,不关注分离原则,配置和调用不简便

    //传统XHR
    const xhr = new XMLHttpRequest();
    xhr.open('GET',url);
    xhr.onload=function (){
      console.log(xhr.response)
    };
    xhr.onerror=function (){
      console.log('error')
    };
    xhr.send();
    
    //fetch+await
    try {
      const res = await fetch(url);
      const data = await res.json();
      console.log(data);
    }catch(error){
      console.log(error)
    }
    
    
  3. 特点:

    • 关注分离
    • 是原生函数,不再使用XmlHttpRequest对象提交ajax请求
    • 老版本浏览器可能不支持

第五章 React 路由

5.1 相关概念

  1. SPA(single page web application)单页面应用

    1. 只有一个主页面
    2. 点击页面中的链接不会刷新页面,只会做页面的局部更新
    3. 数据都需要通过ajax请求获取,并在前端异步展现
  2. 路由

    1. 概念:

      一个路由就是一个映射关系(key:value)

      key–path , value–function/component

    2. 分类

      1. 后端路由

        • value 为function
        • 注册路由 route.get(path,function(req,res){})
        • 工作原理:当node接收到一个请求时,根据请求路径找到匹配的路由,调用路由中的函数来处理请求,返回数据
      2. 前端路由

        • value为component
        • 注册路由:<Route path='/test' component={Test}
        • 工作原理:当浏览器的path变为‘/test’时,组件变为Test组件
      3. 浏览器中的历史记录是栈结构

        History对象

        //方法一,直接使用H5推出的history身上的API
        let history = History.createBrowserHistory() 
        //方法二:hash值/锚点
        let history = History.createHashHistory()
            //留下历史记录
        		function push (path) {
        			history.push(path)
        			return false
        		}
        	//替换历史记录的栈顶
        		function replace (path) {
        			history.replace(path)
        		}
        	//回退
        		function back() {
        			history.goBack()
        		}
        	//前进
        		function forword() {
        			history.goForward()
        		}
        	//监听历史记录
        		history.listen((location) => {
        			console.log('请求路由路径变化了', location)
        		})
        

5.2 基本路由使用

//1.明确好界面中的导航区、展示区

//2.编写路由链接
<BrowserRouter(HashRouter)>
<Link className="list-group-item" to="/about">About</Link>
<Link className="list-group-item" to="/home">Home</Link>
</BrowserRouter(HashRouter)>

//3.匹配路由,注意这里的component首字母不要大写!
<Route path='/about' component={About}/>
<Route path='/home' component={Home}/>
  
//4.<App>的最外侧包裹一个<BrowserRouter>或者<HashRouter>

5.2.1 路由组件和一般组件

  1. 写法不同:

    一般:<Demo/>

    路由:<Route path='/demo',component={Demo}/>

  2. 存放位置不同

    一般:components

    路由:pages

  3. 接收到的props不同:

    一般组件:写组件标签时传递什么就收到什么

    路由:接收到三个固定属性

    history:
        action: "POP"
        block: ƒ block(prompt)
        createHref: ƒ createHref(location)
        go: ƒ go(n)
        goBack: ƒ goBack()
        goForward: ƒ goForward()
        length: 8
        listen: ƒ listen(listener)
        location: {pathname: "/about", search: "", hash: "",         								state: undefined}
        push: ƒ push(path, state)
        replace: ƒ replace(path, state)
        __proto__: Object
        
    location:
        hash: ""
        pathname: "/about"
        search: ""
        state: undefined
        
    match:
        isExact: true
        params: {}
        path: "/about"
        url: "/about"
        __proto__: Object
        staticContext: undefined
    

5.2.2 NavLink与封装NavLink

  1. NavLink可实现路由链接的高亮,通过activeClassName指定样式名
  2. 标签体内容是一个特殊的标签属性
  3. 通过this.props.children 可以获取标签体内容
<MyNavLink to='about'>About</MyNavLink>
//封装
<NavLink activeClassName="atguigu" className="list-group-item" {...this.props}></NavLink>

5.2.3 Switch组件

提高匹配路由效率(单一匹配)

<Switch></Switch>

5.2.4 解决多级路径刷新页面时样式丢失问题

  1. 去掉 ‘.’ ,./从当前文件出发
  2. 在样式路径最前面添加 %PUBLIC_URL%
  3. HashRouter,#后面都是哈希值(少见)

5.2.5 路由的精准匹配和模糊匹配

  1. 默认使用模糊匹配:输入路径必须包含匹配路径,且顺序要一致
  2. 开启严格匹配:<Route exact={true} path="/about" component={About}/>
  3. 严格匹配不要随便开启,需要再开,有时开启会导致无法继续匹配二级路由

5.2.6 Redirect

  1. 一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由

  2. <Switch>
      <Route path='/about' component={About}/>
    	<Route path='/home' component={Home}/>
      <Redirect to='about'/>
    </Switch>
    

5.3 路由的嵌套

  1. 注册子路由时要写上父路由的path值
  2. 路由的匹配是按照注册路由的顺序进行的

5.4 向路由组件传递参数

  1. param参数

    //1. 路由链接(携带参数)
    <Link to='/home/message/detail/tom/18'>详情</Link>
    //2. 注册路由(接受参数)
    <Route path='/home/message/detail/:name/:age' component={Detail} />
    //3. 接收参数
      const {name,age} = this.props.match.params;
    
  2. search参数

    //1. 路由链接(携带参数)
    <Link to='/home/message/detail?name=tom&age=18'>详情</Link>
    //2. 注册路由(无需声明接收参数)
    <Route path='/home/message/detail' component={Detail} />
    //3. 接收参数,获取到的是urlencode编码字符串,需要借助querystring解析
      const {name,age}=qs.parse(this.props.location.search.slice(1))
    
  3. state参数

    //1. 路由链接(携带参数)
    <Link to={{pathname:'/home/message/detail',state:{name:tom,age:18}}}>详情</Link>
    //2. 注册路由
    <Route path='/home/message/detail' component={Detail} />
    //3. 接收参数
    const {name,age}=this.props.location.state;
    //刷新也可以保留参数
    

5.6 多种路由跳转方式

  1. push

  2. replace

    <Link replace=true to='/home'>home</Link>

  3. 编程式路由导航

    借助this.props.history对象上的API操作路由跳转、前进、后退

    this.props.history.push/replace/goBack/goForward/go()
    
  4. withRouter

    作用:加工一般组件使其具有路由组件上的history对象,其返回值是一个新的组件

5.7 HashRouter与BrowserRouter的区别

HashRouterBrowserRouter
底层原理URL的哈希值H5新增的history API,不兼容IE9及以下版本
path表现形式路径包含 #路径不包含#
刷新后对路由state参数的影响state参数丢失对state没有影响,因为state保存在history中
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值