资讯专栏INFORMATION COLUMN

阅读ant-design源码_Button

xinhaip / 589人阅读

摘要:组件整体组件主要是通过改变状态,从而渲染时应用不同来改变外观检查是否只有个中文字符,例如提交,检查到则会变更中的属性,再次渲染时就会变为提交中会检查是否需要状态渲染的中绑定了,通过方法延迟执行动画注意学习使用和的使用使用与使用的比较,前者更

Button组件

整体

Button组件

主要是通过改变state状态,从而渲染时应用不同className来改变外观

检查是否只有2个中文字符,例如 "提交", 检查到则会变更state中的属性,再次渲染时就会变为 "提 交"

componentWillReceiveProps中会检查是否需要loading状态

渲染的dom中绑定了click,通过setTimeout方法延迟执行click动画

注意

学习使用classNames和omit

React.cloneElement的使用

使用React.children与使用this.props.children的比较,前者更准确

每次render通过改变className来改变外观和动画

源码注释
import * as React from "react";
import { findDOMNode } from "react-dom";
import PropTypes from "prop-types";
import classNames from "classnames";
import omit from "omit.js";
import Icon from "../icon";
import Group from "./button-group";

//2个中文字符
const rxTwoCNChar = /^[u4e00-u9fa5]{2}$/;
const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar);
function isString(str: any) {
  return typeof str === "string";
}

// Insert one space between two chinese characters automatically.

function insertSpace(child: React.ReactChild, needInserted: boolean) {
  // Check the child if is undefined or null.
  if (child == null) {
    return;
  }
  const SPACE = needInserted ? " " : "";
  // strictNullChecks oops.
  // child是react的组件并且组件的子元素只有2个中文字符
  // 如果是点击,child是一个obj,里面type为"span"
  if (typeof child !== "string" && typeof child !== "number" &&
    isString(child.type) && isTwoCNChar(child.props.children)) {
    // 克隆组件(element,[props],[...children])
    // 也可以写成
    // {child.props.children.split("").join(SPACE)}
    return React.cloneElement(child, {},
      child.props.children.split("").join(SPACE));
  }
  // child是字符串
  if (typeof child === "string") {
    // child只有2个中文字符
    if (isTwoCNChar(child)) {
      child = child.split("").join(SPACE);
    }
    return {child};
  }
  return child;
}

export type ButtonType = "default" | "primary" | "ghost" | "dashed" | "danger";
export type ButtonShape = "circle" | "circle-outline";
export type ButtonSize = "small" | "default" | "large";

export interface BaseButtonProps {
  type?: ButtonType;
  htmlType?: string;
  icon?: string;
  shape?: ButtonShape;
  size?: ButtonSize;
  loading?: boolean | { delay?: number };
  prefixCls?: string;
  className?: string;
  ghost?: boolean;
}

export type AnchorButtonProps = BaseButtonProps & React.AnchorHTMLAttributes;

export type NativeButtonProps = BaseButtonProps & React.ButtonHTMLAttributes;

export type ButtonProps = AnchorButtonProps | NativeButtonProps;

export default class Button extends React.Component {
  static Group: typeof Group;
  static __ANT_BUTTON = true;

  static defaultProps = {
    prefixCls: "ant-btn",
    loading: false,
    ghost: false,
  };

  static propTypes = {
    type: PropTypes.string,
    shape: PropTypes.oneOf(["circle", "circle-outline"]),
    size: PropTypes.oneOf(["large", "default", "small"]),
    htmlType: PropTypes.oneOf(["submit", "button", "reset"]),
    onClick: PropTypes.func,
    loading: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
    className: PropTypes.string,
    icon: PropTypes.string,
  };

  timeout: number;
  delayTimeout: number;

  constructor(props: ButtonProps) {
    super(props);
    this.state = {
      loading: props.loading,
      clicked: false,
      hasTwoCNChar: false,
    };
  }

  //每次创建时
  componentDidMount() {
    //判断子元素是否只有2个字符,并且更改state
    this.fixTwoCNChar();
  }

  //每次prop改变
  componentWillReceiveProps(nextProps: ButtonProps) {
    const currentLoading = this.props.loading;
    const loading = nextProps.loading;

    //如果传了loading
    if (currentLoading) {
      //先清空之前loading的计时器
      clearTimeout(this.delayTimeout);
    }
    //loading不为布尔值,并且存在delay属性(自定义loadidng延迟)
    if (typeof loading !== "boolean" && loading && loading.delay) {
      this.delayTimeout = window.setTimeout(() => this.setState({ loading }), loading.delay);
    } else {
      //未自定义loading延迟
      this.setState({ loading });
    }
  }

  //每次更新render后,检查是否2中文字符
  componentDidUpdate() {
    this.fixTwoCNChar();
  }

  componentWillUnmount() {
    if (this.timeout) {
      clearTimeout(this.timeout);
    }
    if (this.delayTimeout) {
      clearTimeout(this.delayTimeout);
    }
  }

  //判断子元素是否只有2个字符,并且将判断结果给state.hasTwoCNChar
  fixTwoCNChar() {
    // Fix for HOC usage like 
    //返回已经装在的DOM(这里可能是或者

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108075.html

相关文章

  • 组件库按需加载 借助babel-plugin-import实现

    摘要:对于大中型前端项目为了解耦与复用,更多的公司会选择自己封装组件库,那么一次引入整个组件库必然导致项目过大,如何按需加载则必须要做前世的插件原理项目地址在转码的时候,把整个库的引用,变为具体模块的引用。 对于大中型前端项目为了解耦与复用,更多的公司会选择自己封装组件库,那么一次引入整个组件库必然导致项目过大,如何按需加载则必须要做 前世 ant-design的babel插件babel-p...

    zhichangterry 评论0 收藏0
  • React + MobX 入门及实例(二)

    摘要:在上一章入门及实例一应用实例的基础上增加优化界面增加后台框架,操作。删除选中项时,一定要在删除成功后将置空,否则在下次选择时会选中已删除的项,虽然没有元素但可能会影响其他一些操作。中设置跨域访问实际是对进行匹配。 在上一章 React + MobX 入门及实例(一) 应用实例TodoList的基础上 增加ant-design优化界面 增加后台express框架,mongoose操作。...

    Eidesen 评论0 收藏0
  • 剖析 React 源码:先热个身

    摘要:我们先来看下这个函数的一些神奇用法对于上述代码,也就是函数来说返回值是。不管你第二个参数的函数返回值是几维嵌套数组,函数都能帮你摊平到一维数组,并且每次遍历后返回的数组中的元素个数代表了同一个节点需要复制几次。这是我的 React 源码解读课的第一篇文章,首先来说说为啥要写这个系列文章: 现在工作中基本都用 React 了,由此想了解下内部原理 市面上 Vue 的源码解读数不胜数,但是反观...

    sean 评论0 收藏0
  • TypeScript 、React、 Redux和Ant-Design的最佳实践

    摘要:使用官方的的另外一种版本和一起使用自动配置了一个项目支持。需要的依赖都在文件中。带静态类型检验,现在的第三方包基本上源码都是,方便查看调试。大型项目首选和结合,代码调试维护起来极其方便。 showImg(https://segmentfault.com/img/bVbrTKz?w=1400&h=930); 阿特伍德定律,指的是any application that can be wr...

    wangbinke 评论0 收藏0

发表评论

0条评论

xinhaip

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<