最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談react-router@4.0 使用方法和源碼分析

 更新時間:2019年06月04日 10:05:40   作者:僅此而已  
這篇文章主要介紹了淺談react-router@4.0 使用方法和源碼分析,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

react-router-dom@4.3.0 || react-router@4.4.1

react-router 使用方法

配置 router.js

import React, { Component } from 'react';
import { Switch, Route } from 'react-router-dom';

const router = [{
  path: '/',
  exact: true,
  component:importPath({
   loader: () => import(/* webpackChunkName:"home" */ "pages/home/index.js"),
  }),
 },]
const Routers = () => (
 <main>
  <Switch>
   {
    router.map(({component,path,exact},index)=>{
     return <Route exact={exact} path={path} component={component} key={path} />
    })
   }
  </Switch>
 </main>
);

export default Routers;

入口 index.js

import {HashRouter} from 'react-router-dom';
import React from 'react';
import ReactDOM from 'react-dom';
import Routers from './router';

ReactDOM.render (
   <HashRouter>
    <Routers />
   </HashRouter>,
 document.getElementById ('App')
);

home.js

import { withRouter } from "react-router-dom";

@withRouter
class Home extends React.Component<PropsType, stateType> {
 constructor(props: PropsType) {
  super(props);
  this.state = {};
 }
 goPath=()=>{
   this.props.history.push('/home')
 }
 render() {
  return (
   <div onClick={this.goPath}>home</div>
  );
 }
export default Home;

react-router 源碼解析

下面代碼中會移除部分的類型檢查和提醒代碼,突出重點代碼

第一步 Switch react-router

function _possibleConstructorReturn(self, call) {
 if (!self) {
  throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
 }
 if(call&&(typeof call === "object" || typeof call === "function") ){
  return call
 }else {
  return self
 }
}
var Switch = function (_React$Component) {
 function Switch() {
  //使用傳遞進來的組件覆蓋本身
  return _possibleConstructorReturn(this, _React$Component.apply(this, arguments)); 
 }
 Switch.prototype.render = function render() {
  var route = this.context.router.route;
  var children = this.props.children;
  var location = this.props.location || route.location;
  var match = void 0,child = void 0;
  
  //檢查element是否是react組件,初始match為null,
  React.Children.forEach(children, function (element) {
   //如果match符合,forEach不會進入該if
   if (match == null && React.isValidElement(element)) { 
    var _element$props = element.props,
      pathProp = _element$props.path,
      exact = _element$props.exact,
      strict = _element$props.strict,
      sensitive = _element$props.sensitive,
      from = _element$props.from;
    var path = pathProp || from;
    child = element; 
    //檢查當前配置是否符合,
    match = matchPath(location.pathname, { path: path, exact: exact, strict: strict, sensitive: sensitive }, route.match); 
   }
  });
  //如果有匹配元素,則返回克隆child
  return match ? React.cloneElement(child, { location: location, computedMatch: match }) : null;
 };

 return Switch;
}(React.Component);

總結(jié):switch根據(jù)location.pathname,path,exact,strict,sensitive獲取元素并返回element

第二步 Route react-router

var Route = function (_React$Component) {
 function Route() {
  var _temp, _this, _ret;
  //獲取參數(shù)
  for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
   args[_key] = arguments[_key];
  }
  //修改this
  return _ret = (
   _temp = (_this = _possibleConstructorReturn(this, _React$Component.call.apply(_React$Component, [this].concat(args))), _this), 
   //檢查當前元素是否符合match
   _this.state = {match: _this.computeMatch(_this.props,_this.context.router)},_temp),
    //這里是真正return
    _possibleConstructorReturn(_this, _ret); 
 }
 // 設置content
 Route.prototype.getChildContext = function getChildContext() {
  return {
   router: _extends({}, this.context.router, {
    route: {
     location: this.props.location || this.context.router.route.location,
     match: this.state.match
    }
   })
  };
 };
 // 根據(jù)參數(shù)檢查當前元素是否符合匹配規(guī)則
 Route.prototype.computeMatch = function computeMatch(_ref, router) {
  var computedMatch = _ref.computedMatch,
    location = _ref.location,
    path = _ref.path,
    strict = _ref.strict,
    exact = _ref.exact,
    sensitive = _ref.sensitive;

  if (computedMatch) return computedMatch;

  var route = router.route;

  var pathname = (location || route.location).pathname;

  return matchPath(pathname, { path: path, strict: strict, exact: exact, sensitive: sensitive }, route.match);
 };
 // 設置match
 Route.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps, nextContext) {
  this.setState({
   match: this.computeMatch(nextProps, nextContext.router)
  });
 };

 Route.prototype.render = function render() {
  var match = this.state.match;
  var _props = this.props,
    children = _props.children,
    component = _props.component,
    render = _props.render;
  var _context$router = this.context.router,
    history = _context$router.history,
    route = _context$router.route,
    staticContext = _context$router.staticContext;

  var location = this.props.location || route.location;
  var props = { match: match, location: location, history: history, staticContext: staticContext };
  //檢查route 是否有component組
  if (component) return match ? React.createElement(component, props) : null; 
  // 檢查是否包含render 組件
  if (render) return match ? render(props) : null;
  // withRouter 使用的方式
  if (typeof children === "function") return children(props);

  if (children && !isEmptyChildren(children)) return React.Children.only(children);

  return null;
 };

 return Route;
}(React.Component);

總結(jié):route 渲染的方式: component render children,代碼示例用的是component,route 是檢查當前組件是否符合路由匹配規(guī)則并執(zhí)行創(chuàng)建過程

第三步 HashRouter react-router-dom

import Router from './Router'
import {createHistory} from 'history'
var HashRouter = function (_React$Component) {
 function HashRouter() {
  var _temp, _this, _ret;
  //參數(shù)轉(zhuǎn)換為數(shù)組
  for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { 
   args[_key] = arguments[_key];
  }
  return _ret = (
   _temp = (_this = _possibleConstructorReturn(this, _React$Component.call.apply(_React$Component, [this].concat(args))), _this),
    _this.history = createHistory(_this.props), _temp), //創(chuàng)建history
    _possibleConstructorReturn(_this, _ret); //真正返回的東西 返回this
 }
 HashRouter.prototype.render = function render() {
  // 返回一個Router,并且把history,children傳遞給Router
  return React.createElement(Router, { history: this.history, children: this.props.children });
 };
 return HashRouter;
}(React.Component);

總結(jié) 通過 history庫里面 createHistory 創(chuàng)建路由系統(tǒng)

第四部 Router react-router

var Router = function (_React$Component) {
 function Router() {
  var _temp, _this, _ret;
  //獲取參數(shù),和其他組件一樣
  for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
   args[_key] = arguments[_key];
  }
  return _ret = (_temp = (_this = _possibleConstructorReturn(this, _React$Component.call.apply(_React$Component, [this].concat(args))), _this), _this.state = {
   match: _this.computeMatch(_this.props.history.location.pathname) //返回路由對象
  }, _temp), _possibleConstructorReturn(_this, _ret); //返回this
 }
 // 返回context
 Router.prototype.getChildContext = function getChildContext() {
  return {
   router: _extends({}, this.context.router, {
    history: this.props.history,
    route: {
     location: this.props.history.location,
     match: this.state.match
    }
   })
  };
 };
  
 Router.prototype.computeMatch = function computeMatch(pathname) {
  return {
   path: "/",
   url: "/",
   params: {},
   isExact: pathname === "/"
  };
 };

 Router.prototype.componentWillMount = function componentWillMount() {
  var _this2 = this;

  var _props = this.props,
    children = _props.children,
    history = _props.history;

  // 啟動監(jiān)聽 當hash 改變是做一次檢查,并返回unlisten 取消事件
  this.unlisten = history.listen(function () {
   _this2.setState({
    match: _this2.computeMatch(history.location.pathname)
   });
  });
 };
 //銷毀前取消監(jiān)聽
 Router.prototype.componentWillUnmount = function componentWillUnmount() {
  this.unlisten();
 };
 // children是HashRouter 傳遞進來的
 Router.prototype.render = function render() {
  var children = this.props.children;
  return children ? React.Children.only(children) : null;
 };

 return Router;
}(React.Component);

總結(jié) history是一個JavaScript庫,可讓您在JavaScript運行的任何地方輕松管理會話歷史記錄。history抽象出各種環(huán)境中的差異,并提供最小的API,使您可以管理歷史堆棧,導航,確認導航以及在會話之間保持狀態(tài)。

第五部 withRouter <react-router>

var withRouter = function withRouter(Component) {
 var C = function C(props) {
  //獲取props
  var wrappedComponentRef = props.wrappedComponentRef,
    remainingProps = _objectWithoutProperties(props, ["wrappedComponentRef"]);
  // Route 組件 children方式
  return React.createElement(Route, {
   children: function children(routeComponentProps) {
    // 這里使用的是route 組件 children(props)
    //routeComponentProps 實際等于 { match: match, location: location, history: history, staticContext: staticContext };
    return React.createElement(Component, _extends({}, remainingProps, routeComponentProps, {
     ref: wrappedComponentRef
    }));
   }
  });
 };

 C.displayName = "withRouter(" + (Component.displayName || Component.name) + ")";
 C.WrappedComponent = Component;
 // 該類似于object.assign(C,Component),得到的結(jié)果是C
 return hoistStatics(C, Component);
};

到這里真?zhèn)€流程基本結(jié)束了,這只是react-router的一種使用方式的解析,本文的目的是理解react-router的運行機制,如果有什么錯誤還望指出,謝謝

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • VSCode搭建React Native環(huán)境

    VSCode搭建React Native環(huán)境

    這篇文章主要介紹了VSCode搭建React Native環(huán)境,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-05-05
  • 可定制react18 input otp 一次性密碼輸入組件

    可定制react18 input otp 一次性密碼輸入組件

    這篇文章主要為大家介紹了可定制react18 input otp 一次性密碼輸入組件,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • React?模式之純組件使用示例詳解

    React?模式之純組件使用示例詳解

    這篇文章主要為大家介紹了React?模式之純組件使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • React從Class方式轉(zhuǎn)Hooks詳解

    React從Class方式轉(zhuǎn)Hooks詳解

    這篇文章主要介紹了React從Class方式轉(zhuǎn)Hooks詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-09-09
  • 解決React報錯Property does not exist on type 'JSX.IntrinsicElements'

    解決React報錯Property does not exist on 

    這篇文章主要為大家介紹了React報錯Property does not exist on type 'JSX.IntrinsicElements'解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • react實現(xiàn)簡單的拖拽功能

    react實現(xiàn)簡單的拖拽功能

    這篇文章主要為大家詳細介紹了react實現(xiàn)簡單的拖拽功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • React組件useReducer的講解與使用

    React組件useReducer的講解與使用

    在React函數(shù)式組件中,我們可以通過useState()來創(chuàng)建state,這種state創(chuàng)建方式會給我們返回兩個東西state和setState()。
    2023-04-04
  • react分頁顯示數(shù)據(jù)的方法

    react分頁顯示數(shù)據(jù)的方法

    分頁在很多地方都可以用到,本文主要實現(xiàn)了react分頁顯示,主要使用三個組件,父組件listBox、列表組件List、按鈕組件PageButton,感興趣的可以了解一下
    2021-08-08
  • 詳解使用create-react-app添加css modules、sasss和antd

    詳解使用create-react-app添加css modules、sasss和antd

    這篇文章主要介紹了詳解使用create-react-app添加css modules、sasss和antd,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • React路由中的redux和redux知識點拓展

    React路由中的redux和redux知識點拓展

    這篇文章主要介紹了React路由中的redux和redux知識點拓展,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,感興趣的朋友可以參考學習一下
    2022-08-08

最新評論

石家庄市| 珲春市| 莱芜市| 武夷山市| 泰宁县| 云林县| 鹤壁市| 宝鸡市| 盖州市| 东安县| 革吉县| 玉龙| 大田县| 乐都县| 平阳县| 西林县| 青海省| 金秀| 扎兰屯市| 洛宁县| 泸溪县| 墨脱县| 秦安县| 龙里县| 汽车| 沧州市| 兰坪| 和田市| 理塘县| 广元市| 郁南县| 临清市| 东山县| 瑞昌市| 宿州市| 汤原县| 西青区| 鄂温| 夹江县| 修武县| 克东县|