Breadcrumb bread crumbs

Antd’s breadcrumb component is a component that can jump to pages in combination with routing, where support for routing is react-router@3 and react-router@4.

BreadcrumbProps

Again, we start with parameters that a component passes in, and we figure out which parameters it accepts, and then we figure out where those parameters work

  exportinterface BreadcrumbProps { prefixCls? : string;// Style class prefixroutes? :Array<any>; // An array of routesparams? :Object; // A collection of route parameter objectsseparator? : React.ReactNode;// The delimiter between each itemitemRender? :(route: any, params: any, routes: Array<any>, paths: Array<string>) = > React.ReactNode; // A custom function to render itemstyle? : React.CSSProperties;// Inline styleclassName? : string;// Customize the style name
  }Copy the code

Render()

The entry point for the same component is its render function

render() { let crumbs; const { separator, prefixCls, style, className, routes, params = {}, children, itemRender = defaultItemRender, } = this.props; Const paths: string[] = []; if (routes && routes.length > 0) {routes = const paths: string[] = []; // React-router will pass some parameters to the incoming component if the react-router version is less than 4. With the react-Router4 version, we need to build routes, params, routes, routes, routes, routes, routes, routes. Children crumbs = routes. The map ((route) = > {/ / can be seen in the example of official website every route corresponding back parameters as shown in figure below route. The path = the route. The path | | '. Let path: string = route.path.replace(/^\//, ''); Keys (params).foreach (key => {// Replace the path of a single item with the value of the passed parameter path = path.replace(' :${key} ', params[key]); }); If (path) {// If (path) {// If (path) {// If (path) {// If (path) {// If (path) { The remaining // contains the hierarchy in turn, but this method of return is limited to react-router@3 paths.push(path); } return (// then pass in the itemRender function to render items, 'll read this function when you know the role of the paths < BreadcrumbItem separator = {separator} key = {route. BreadcrumbName | | path} > {itemRender (route, params, routes, paths)} </BreadcrumbItem> ); }); } else if (children) {// Render children if there are children, The method used is still react.children.map + react.cloneElement () // I venture to speculate that this code is intended to accommodate the addition of react-router@4 crumbs = React.Children.map(children, (element: any, index) => { if (! element) { return element; } / / the waring function here is antd itself based on HTTP: / / https://www.npmjs.com/package/warning / / encapsulates a browser console box warning print warning tool function (element. The type && element.type.__ANT_BREADCRUMB_ITEM, 'Breadcrumb only accepts Breadcrumb.Item as it\'s children', ); return cloneElement(element, { separator, key: index, }); }); } return ( <div className={classNames(className, prefixCls)} style={style}> {crumbs} </div> ); }Copy the code

Route Indicates the sending parameters

Use the functions required by react-router@3

  // Get the name of the current route
  function getBreadcrumbName(route, params) {
    if(! route.breadcrumbName) {return null;
    }
    / / will all the parameters to use '|' form string segmentation, is used for the following regular matching
    const paramsKeys = Object.keys(params).join('|');
    The first argument to js's replace can be a string or a regular match,
    // The second argument can be a string or a function that returns the replacement string
    const name = route.breadcrumbName.replace(
      // Match the parameters, such as breadcrumbName='Application:id:name'
      / / the string matches a regular here is: ': id | name'
      // The first argument to RegExp() is the text of the regular match expression
      // The second argument is a strict requirement for matching. G is a global match, not a stop after the first match
      new RegExp(` : (${paramsKeys}) `.'g'),
      // This parameter is used if it has a value, and returns no value
      (replacement, key) => params[key] || replacement,
    );
    return name;
  }

  / / render the item
  function defaultItemRender(route, params, routes, paths) {
    // Do not add the link if it is the last item
    const isLastItem = routes.indexOf(route) === routes.length - 1;
    const name = getBreadcrumbName(route, params);
    return isLastItem
      ? <span>{name}</span>
      : <a href={` # / ${paths.join('/')} `} >{name}</a>;
  }Copy the code

BreadcrumbItem

A separate component used to write the items of the Breadcrumb, which I think can be used on react-router@4,

Since react-router@4 now needs to write its own routing hierarchy, this approach is more flexible

BreadcrumbItemProps

Although it is a child component, you still need to start with its parameters

  exportinterface BreadcrumbItemProps { prefixCls? : string;// The namespace prefix of the style classseparator? : React.ReactNode;// Item separatorhref? : string;/ / the connection
  }Copy the code

Render()

The render function is relatively simple

  render() {
    const{ prefixCls, separator, children, ... restProps } =this.props;
    let link;
    // If href is used, use the a tag
    if ('href' in this.props) {
      link = <a className={` ${prefixCls}-link`} {. restProps} >{children}</a>;
    } else {
      link = <span className={` ${prefixCls}-link`} {. restProps} >{children}</span>;
    }
    if (children) {
      return (
        <span>
          {link}
          <span className={` ${prefixCls}-separator`} >{separator}</span>
        </span>
      );
    }
    return null;
  }Copy the code

Component’s identity

There is something in this component that represents its identity

export default class BreadcrumbItem extends React.Component<BreadcrumbItemProps.any> {
  static __ANT_BREADCRUMB_ITEM = true; // Proof that he is a child of an AntBreadcrumbCopy the code

In the render code of the Breadcrumb above, there is a piece of code

  crumbs = React.Children.map(children, (element: any, index) => {
    if(! element) {return element;
    }
    warning(
    // The element. Type here is what you must be thinking about
    // React.children. Map is an example of how to use element
    // React.cloneElement() is almost equivalent to:
    // 
      
       {children}
      
    // the type argument can be either a tag name string (such as 'div' or 'span'), 
    // or a React component type (a class or a function).
    // You can use this id to identify yourself in the future
    // Make the component, don't feel cool
      element.type && element.type.__ANT_BREADCRUMB_ITEM,
      'Breadcrumb only accepts Breadcrumb.Item as it\'s children',);return cloneElement(element, {
      separator,
      key: index,
    });
  });Copy the code