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 = (
      
{renderIndicator(prefixCls, this.props)} {tip ?
{tip}
: null}
); // spin作为容器是的渲染内容 if (this.isNestedPattern()) { const containerClassName = classNames(`${prefixCls}-container`, { [`${prefixCls}-blur`]: spinning, }); return (
{spinning &&
{spinElement}
}
{this.props.children}
); } return spinElement; }; render() { return {this.renderSpin}; } // 渲染加载中样式 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 ( ); }
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状态时控制显示和隐藏的,会频繁传递,那么我们对这个状态有和上一个状态进行比较。一样的话。不渲染页面。性能方面就会有一定的优化

你可能感兴趣的:(antd源码)