Ant Design 源码批判性学习 Button 组件(一) type

306 阅读1分钟

收获:

就是antd写的好的地方

  1. 如何写className
    // bad
    
     const getTypeClass = (type: typeType)=>{
         if(typeof type === 'undefined'){
             return sc()
         }
         return classNames(sc(), sc(type))
     }
     return (
         <button className={getTypeClass(type)}>{children}</button>
     )
    
    
    
     //good
     const classname = classNames(sc(),{
         [sc(type)]: type,
     }, className)
    
     return (
         <button className={classname}>{children}</button>
     )
    
    

建议:

觉得antd有待改进的代码, 并给出改进的方法

  1. 写className有重复代码, 建议用一个高阶函数来减少重复

    
    // antd 
    const classes = classNames(
      prefixCls,
      {
        [`${prefixCls}-${shape}`]: shape !== 'default' && shape, // Note: Shape also has `default`
        [`${prefixCls}-${type}`]: type,
        [`${prefixCls}-${sizeCls}`]: sizeCls,
        [`${prefixCls}-icon-only`]: !children && children !== 0 && !!iconType,
        [`${prefixCls}-background-ghost`]: ghost && !isUnborderedButtonType(type),
        [`${prefixCls}-loading`]: innerLoading,
        [`${prefixCls}-two-chinese-chars`]: hasTwoCNChar && autoInsertSpace,
        [`${prefixCls}-block`]: block,
        [`${prefixCls}-dangerous`]: !!danger,
        [`${prefixCls}-rtl`]: direction === 'rtl',
      },
      className,
    );
    
    
    // good
    export const scopedClassMaker = (prefix: string) => {
        return (name?: string) => {
            return [prefix, name].filter(Boolean).join('-');
        };
    };
    const scopedClass = scopedClassMaker(prefixCls)
    const sc = scopedClass;
    
    const classes = classNames(
        prefixCls,
        {
            [sc(shape)]: shape !== 'default' && shape, // Note: Shape also has `default`
            [sc(type)]: type,
            [sc(sizeCls)]: sizeCls,
            [sc('icon-only')]: !children && children !== 0 && !!iconType,
            [sc('background-ghost')]: ghost && !isUnborderedButtonType(type),
            [sc('loading')]: innerLoading,
            [sc('two-chinese-chars')]: hasTwoCNChar && autoInsertSpace,
            [sc('block')]: block,
            [sc('dangerous')]: !!danger,
            [sc('rtl')]: direction === 'rtl',
        },
        className,
    );
    
  2. type 写的太麻烦复杂:

    // antd
    export const tuple = <T extends string[]>(...args: T) => args;
    const ButtonTypes = tuple('default', 'primary', 'ghost', 'dashed', 'link', 'text');
    export type ButtonType = typeof ButtonTypes[number];
    
    //good
    export type ButtonType = 'default'|'primary'|'ghost'|'dashed'|'link'|text';