Web API Router for React

⚑ Web API Router

Web API Router for React

监听地址栏的变动:

  • requestAnimationFrame 动态侦测
  • window.addEventListener("hashchange", handler);

判断浏览器是否支持 onhashchange 事件

if (('onhashchange' in window) && ((typeof document.documentMode === 'undefined') || document.documentMode == 8)) {
    window.onhashchange = function () {
        console.log(location.hash);
    };
}

主程序,提供 Blog、UseEffect、Passthrough 等任意个组件以测试:

import React, {useState, useEffect} from "react"
import ReactDOM from 'react-dom';

import router from '/router.js';
import Blog from '/cp/keyedList.js';
import UseEffect from '/cp/useEffect.js';
import Passthrough from '/cp/passthrough.js';

let Category = () => {
  const [n, setN] = React.useState(0);
  return (
    <>
    <div className="grid">
      <div className="col15">      
      <h1>Router</h1>
      <a href="#/start" onClick={router.start}>Start</a>
      <a href="#/stop" onClick={router.stop}>Stop</a>
      </div>
      <div className="col15">
      <h1>Module</h1>
      <a onClick={ev => setN(n)} href="#/blog">Blog</a>
      <a onClick={ev => setN(n)} href="#/useEffect">useEffect</a>
      <a onClick={ev => setN(n)} href="#/hr">hr</a>
      <a onClick={ev => setN(n)} href="#/Passthrough">Passthrough</a>
      </div>
    </div>
    <div className="grid">
      <router.Root>
        <router.Route path="/hr" cp={<div style={{width:'100%'}}><hr />🚩</div>} />
        <router.Route path="/useEffect" cp={<UseEffect />} />
        <router.Route path="/blog" cp={<Blog />} />
        <router.Route path="/Passthrough" cp={<Passthrough />} />        
      </router.Root>
    </div>
    </>
  )
}

ReactDOM.render(
  <Category />,
  document.getElementById('root')
);

router.js

import React from 'react';

// Polyfill
window.requestAnimationFrame = (function () {
    if (!window.cancelAnimationFrame) {
        window.cancelAnimationFrame = function (id) {
            clearTimeout(id);
        };
    }
    return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function (callback) {
            window.setTimeout(callback, 1000 / 60);
        };
})();

let router = ((requestAnimationFrame,cancelAnimationFrame)=>{
  let that, requestid, prev = {}, setS,
  fs = ['host', 'hostname', 'href', 'origin', 'pathname', 'port', 'protocol', 'hash'];
  fs.map(it=>prev[it]=location[it]);
  
  let monitor = () => {
    if(prev.href !== location.href){
      fs.map(it=>prev[it]=location[it]);
      //console.log('change', location.hash);
      setS && setS();
    }
    requestid = requestAnimationFrame(monitor);
  }
  let isMe = (path) => {
    return '#'+path === location.hash;
  }
  return (that = {
    start: ()=>{
      that.stop()
      monitor();
    },
    stop: ()=>{
      cancelAnimationFrame(requestid);
    },
    Root: (props) => {
      const [state, setState] = React.useState(false);
      setS = () => setState(!state);
      let found;
      props.children && props.children.map(it => {
        if(isMe(it.props.path)){
            console.log('Root', isMe(it.props.path), it.props.path, it);
            found = (<>{it.type(it.props)}</>);
        }
      })
      return found;
    },
    Route: (props) => {
      //console.log('Route', isMe(props.path), props.path, location.hash);
      return( isMe(props.path)? <>{props.cp}</>:null );
    }
  });
})(requestAnimationFrame,cancelAnimationFrame)

router.start();

export default router;

在线观看 https://scrimba.com/scrim/cB32EPsv

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 引言 我们日常中使用 react 开发项目,那么一定会跟 react-rouer 打交道,但是由于 react 路...
    Cryptic阅读 4,306评论 0 2
  • vue-router两种模式,hash,history 为了构建SPA(单页面应用),需要引入前端路由系统,这就是...
    丘可_2874阅读 10,161评论 1 1
  • 以下内容主要参考自 深入理解 react-router 路由系统react-router的实现原理前端路由实现与 ...
    zhulichao阅读 5,514评论 0 1
  • 前端两种路由方案 无hash通过h5的pushState、replaceState、go、forward、back...
    吴晗君阅读 5,174评论 0 0
  • 前提: 异步交互体验的更高级版本就是 SPA ,大型单页应用最显著特点之一就是采用前端路由系统,通过改变URL,在...
    tency小七阅读 4,021评论 0 1