美文网首页
Web API Router for React

Web API Router for React

作者: 坚果jimbowhy | 来源:发表于2021-01-28 19:21 被阅读0次

    ⚑ 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

    相关文章

      网友评论

          本文标题:Web API Router for React

          本文链接:https://www.haomeiwen.com/subject/cauxtltx.html