浅い話[email protected]使用方法とソース分析


[email protected]𞓜𞓜[email protected]
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);

まとめ:switchはlocations.pathname、path、exact、strict、sensitiveによって要素を取得して、elementに戻ります。
第二ステップRoute react-router

var Route = function (_React$Component) {
 function Route() {
  var _temp, _this, _ret;
  //    
  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
    }
   })
  };
 };
 //                   
 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);

要約:routeレンダリングの方式:component render children、コード例はcomponent、routeは、現在のコンポーネントがルーティングマッチング規則に適合しているかどうかを確認し、作成プロセスを実行することです。
ステップ3 HashRouter react-router-dom

import Router from './Router'
import {createHistory} from 'history'
var HashRouter = function (_React$Component) {
 function HashRouter() {
  var _temp, _this, _ret;
  //       
  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), //  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);
まとめはhistoryライブラリ内のcreateHistoryを通じてルートシステムを作成します。
第四部Router react-router

var Router = function (_React$Component) {
 function Router() {
  var _temp, _this, _ret;
  //    ,       
  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;

  //       hash         ,   unlisten     
  this.unlisten = history.listen(function () {
   _this2.setState({
    match: _this2.computeMatch(history.location.pathname)
   });
  });
 };
 //       
 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);

まとめhistoryはJavaScriptライブラリで、JavaScriptで実行される任意の場所で簡単に会話履歴を管理できます。historyは、様々な環境の違いを抽象化し、最小のAPIを提供して、歴史的なスタック、ナビゲーション、ナビゲーション、セッション間の状態を確認することができます。
第五部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),      C
 return hoistStatics(C, Component);
};

ここまでの流れは基本的に終わりました。これはreact-routerの使用方法の解析にすぎません。本稿の目的はreact-routerの運行メカニズムを理解することです。もし何か間違いがあったら指摘してください。ありがとうございます。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。