首页 > 其他分享 >经常被问到的react-router实现原理详解

经常被问到的react-router实现原理详解

时间:2022-11-02 09:12:43浏览次数:52  
标签:React return js react window 详解 props router

在单页面应用如日中天发展的过程中,备受关注的少了前端路由

而且还经常会被xxx面试官问到,什么是前端路由,它的原理的是什么,它是怎么实现,跳转不刷新页面的...

一大堆为什么,问你头都大

前言

今天主要讲的是:

  • 原生js实现hashRouter
  • 原生js实现historyRouter
  • react-router-dom的BrowserRouter
  • react-router-dom的HistoryRouter

四种路由的实现原理。

环境问题

因为等一下要用到h5新增的pushState() 方法,因为这玩(diao)意(mao)太矫情了,不支持在本地的file协议运行,不然就会报以下错误

在这里插入图片描述

只可以在http(s)协议 运行,这个坑本渣也是踩了很久,踩怀疑自己的性别。

既然用file协议 不行那就只能用webpack搭个简陋坏境了,你也可以用阿帕奇,tomcat...啊狗啊猫之类的东西代理。

本渣用的是webpack环境,也方便等下讲解react-router-dom的两个路由的原理。环境的配置,我简单的贴一下,这里不讲。

npm i webpack webpack-cli babel-loader @babel-core @babel/preset-env html-webpack-plugin webpack-dev-server -D

webpack.config.js

const path = require('path')

const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {

    entry:path.resolve(__dirname,'./index.js'),

    output:{

        filename:'[name].[hash:6].js',

        path:path.resolve(__dirname,'../dist')

    },

    module:{

        rules:[
            {
                test:/\.js$/,

                exclude:/node_module/,

                use:[
                    {
                        loader:'babel-loader',
                        options:{
                            presets:['@babel/preset-env']
                        }
                    }
                ]
            }
        ]

    },

    plugins:[
        new HtmlWebpackPlugin({
            template:path.resolve(__dirname,'./public/index.html'),
            filename:'index.html'
        })
    ]

}

package.json的script添加一条命令

    "dev":"webpack-dev-server --config ./src/webpack.config.js --open"

项目目录
在这里插入图片描述

运行

npm run dev

现在所有东西都准备好了,我们可以进入主题了。

原生js实现hashRouter

html

<ul>
    <li><a href='#/home'>home</a></li>
    <li><a href='#/about'>about</a></li>
    <div id="routeView"></div>
</ul>

js

window.addEventListener('DOMContentLoaded', onl oad)

window.addEventListener('hashchange', changeView)

let routeView = ''

function onl oad() {

    routeView = document.getElementById('routeView')

    changeView()

}

function changeView() {
    switch (location.hash) {
        case '#/home':
            routeView.innerHTML = 'home'
            break;
        case '#/about':
            routeView.innerHTML = 'about'
            break;
    }

}

原生js实现hashRouter主要是监听它的hashchange事件的变化,然后拿到对应的location.hash更新对应的视图

原生js实现historyRouter

html

<ul>
    <li><a href='/home'>home</a></li>
    <li><a href='/about'>about</a></li>
    <div id="routeView"></div>
</ul>

historyRoute

window.addEventListener('DOMContentLoaded', onl oad)

window.addEventListener('popstate', changeView)

let routeView = ''

function onl oad() {

    routeView = document.getElementById('routeView')

    changeView()

    let event = document.getElementsByTagName('ul')[0]

    event.addEventListener('click', (e) => {

        if(e.target.nodeName === 'A'){
            e.preventDefault()

            history.pushState(null, "", e.target.getAttribute('href'))

            changeView()
        }

    })
}

function changeView() {
    switch (location.pathname) {
        case '/home':
            routeView.innerHTML = 'home'
            break;
        case '/about':
            routeView.innerHTML = 'about'
            break;
    }

}

能够实现history路由跳转不刷新页面得益与H5提供的pushState(),replaceState()等方法,这些方法都是也可以改变路由状态(路径),但不作页面跳转,我们可以通过location.pathname来显示对应的视图

react-router-dom

react-router-dom是react的路由,它帮助我们在项目中实现单页面应用,它提供给我们两种路由一种基于hash段实现的HashRouter,一种基于H5Api实现的BrowserRouter

下面我们来简单用一下。

如果你在用本渣以上提供给你的环境,还要配置一下,下面

标签:React,return,js,react,window,详解,props,router
From: https://www.cnblogs.com/xiatianweidao/p/16849854.html

相关文章

  • 深度讲解React Props
    一、props的介绍当React遇到的元素是用户自定义的组件,它会将JSX属性作为单个对象传递给该组件,这个对象称之为“props”。函数声明的组件,会接受一个props形参,获取属性传递......
  • 详解var、let与const
    一、var关键字的特性1.变量作用域在引入ES6的let和const关键字之前,使用var关键字声明的变量只有全局作用域和函数作用域,是没有块级作用域的。这意味着,变量在声......
  • 前端面试指南之React篇(二)
    react中这两个生命周期会触发死循环componentWillUpdate生命周期在shouldComponentUpdate返回true后被触发。在这两个生命周期只要视图更新就会触发,因此不能再这两个生命......
  • React的useLayoutEffect和useEffect执行时机有什么不同
    我们先看下React官方文档对这两个hook的介绍,建立个整体认识useEffect(create,deps):该Hook接收一个包含命令式、且可能有副作用代码的函数。在函数组件主体内(这......
  • 前端面试指南之React篇(一)
    组件之间传值父组件给子组件传值在父组件中用标签属性的=形式传值在子组件中使用props来获取值子组件给父组件传值在组件中传递一个函数在子组件中用props来获取......
  • React循环DOM时为什么需要添加key
    一、React渲染流程和更新流程react渲染流程:jsx->虚拟dom->真实domreact更新流程:props/state改变->render函数重新执行->生成新的虚拟dom树->新旧虚拟dom树进......
  • Vue-router与路由
    Vuex的使用1.vue的插件,增强了vue的功能-在vue中实现集中式状态(数据)管理的一个vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方......
  • 详解Three.js环境搭建与一个简单例子
    一、环境准备1.开发工具选用WebStorm,因为WebStorm自带了一个本地服务器,而Three.js的很多特性需要在服务器端才能展现。2.three.js库的下载与导入3.打开调用three.js的html的......
  • Java实现优化版【快速排序】+四度优化详解
    参考书目:《大话数据结构》一:快速排序1.基本思想:通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续......
  • 今日内容 Vuex 和Vue-router的使用
    Vuex的使用作用vue的插件,增强了vue的功能  在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信......