antd源码-spin解析

antd源码-spin解析

spin的作用是代表当前块正在加载中

Spin
元素的渲染
 renderSpin = ({ getPrefixCls }: ConfigConsumerProps) => {
    const {
      prefixCls: customizePrefixCls,
      className,
      size,
      tip,
      wrapperClassName,
      style,
      ...restProps
    } = this.props;
    const { spinning } = this.state;

    const prefixCls = getPrefixCls('spin', customizePrefixCls);
    const spinClassName = classNames(// 组织spin的样式类
      prefixCls,
      {
        [`${prefixCls}-sm`]: size === 'small',
        [`${prefixCls}-lg`]: size === 'large',
        [`${prefixCls}-spinning`]: spinning,
        [`${prefixCls}-show-text`]: !!tip,
      },
      className,
    );

    // fix https://fb.me/react-unknown-prop
     // 排除不需要的props
    const divProps = omit(restProps, ['spinning', 'delay', 'indicator']);
	// 默认spin内容
    const spinElement = (
      <div {...divProps} style={style} className={spinClassName}>
        {renderIndicator(prefixCls, this.props)}
        {tip ? <div className={`${prefixCls}-text`}>{tip}</div> : null}
      </div>
    );
// spin作为容器是的渲染内容
    if (this.isNestedPattern()) {
      const containerClassName = classNames(`${prefixCls}-container`, {
        [`${prefixCls}-blur`]: spinning,
      });
      return (
        <div {...divProps} className={classNames(`${prefixCls}-nested-loading`, wrapperClassName)}>
          {spinning && <div key="loading">{spinElement}</div>}
          <div className={containerClassName} key="container">
            {this.props.children}
          </div>
        </div>
      );
    }
    return spinElement;
  };

  render() {
    return <ConfigConsumer>{this.renderSpin}</ConfigConsumer>;
  }
	// 渲染加载中样式
  function renderIndicator(prefixCls: string, props: SpinProps): React.ReactNode {
  const { indicator } = props;
  const dotClassName = `${prefixCls}-dot`;

  // should not be render default indicator when indicator value is null
  if (indicator === null) {
    return null;
  }
	// 有接收到indicator参数,使用传入进来的组件作为加载中样式渲染
  if (React.isValidElement(indicator)) {
    return React.cloneElement(indicator, {
      className: classNames(indicator.props.className, dotClassName),
    });
  }
	// 有设置全局加载样式,渲染全局的。
  if (React.isValidElement(defaultIndicator)) {
    return React.cloneElement(defaultIndicator as SpinIndicator, {
      className: classNames((defaultIndicator as SpinIndicator).props.className, dotClassName),
    });
  }

  return (
    <span className={classNames(dotClassName, `${prefixCls}-dot-spin`)}>
      <i className={`${prefixCls}-dot-item`} />
      <i className={`${prefixCls}-dot-item`} />
      <i className={`${prefixCls}-dot-item`} />
      <i className={`${prefixCls}-dot-item`} />
    </span>
  );
}
spin状态的控制和delay的处理
  originalUpdateSpinning: () => void;

  constructor(props: SpinProps) {
    super(props);

    const { spinning, delay } = props;
    const shouldBeDelayed = shouldDelay(spinning, delay);
    this.state = {
      spinning: spinning && !shouldBeDelayed,
    };
    this.originalUpdateSpinning = this.updateSpinning;
    this.debouncifyUpdateSpinning(props);
  }

  componentDidMount() {
    this.updateSpinning();
  }

  componentDidUpdate() {
    this.debouncifyUpdateSpinning();
    this.updateSpinning();
  }

  componentWillUnmount() {
    this.cancelExistingSpin();
  }

  debouncifyUpdateSpinning = (props?: SpinProps) => {
    const { delay } = props || this.props;
    if (delay) {
      this.cancelExistingSpin();
        // 运用防抖的方式
      this.updateSpinning = debounce(this.originalUpdateSpinning, delay);
    }
  };

  updateSpinning = () => {
    const { spinning } = this.props;
    const { spinning: currentSpinning } = this.state;
      // 为什么这里判断一次,是为了避免频繁触发更新dom,只有必要刷新的时候去更新dom,一丢丢性能方面的考虑
    if (currentSpinning !== spinning) {
      this.setState({ spinning });
    }
  };
spin总结
  1. 组件的构建,一个组件,应该将组件拆分,拆分为不同的细小的部分,将问题分开,一个小的单元独立,单元与单元之间关联弱关联

    spin分析:

    • 整个spin组件进入,有两条支路,

      一是有没有接收到自定义描述文档tip,有的话需要渲染描述文字,

      二是有没有children,有children渲染的内容在其spin基础之上套了在渲染。这里分解了问题,但又组装在一起。

      组件的拆分,在我们看来加载中样式已经时一个很小的组件了,但是在这里还是拆开来了的,约为三部分,一、加载中组件。二、加载描述文案。三、加载背面内容文案。

    • 防抖节流的理解

      我对于防抖和节流的理解,我用游戏来说,我们常玩的lol,有技能的释放和回城。防抖(debounce)就是回城,当我们连续按B键时,他会重新开始计时,等设置的时间过去了才会回城,而节流就是技能的释放和冷却,我们第一次释放了技能,在继续释放技能,会告诉你技能正在冷却

    • 性能优化的一点技巧

      this.setState会触发更新,也只有这个会触发页面的更新操作,我们传递的spining状态时控制显示和隐藏的,会频繁传递,那么我们对这个状态有和上一个状态进行比较。一样的话。不渲染页面。性能方面就会有一定的优化

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值