Ant-design踩坑

Antd.Form

踩坑
  1. 经过getFieldDecorator的注册后,所以的onChange函数会被接管。本身的onChange可能会失效。

  2. 如果getFieldDecorator包裹的content包含多个child,要注意封装成一个组件,不要直接在content里用Fragment包裹多个节点,可能有隐患埋坑。如果希望包裹一个或多个组件,需要单独额外去封装一个组件来,会增加文件层级,繁琐!

  3. 自定义的validator,要注意函数里关于value的前置校验,如果没有在validateFields的option配置里设置option.first = true,校验规则会依次校验下去,这个时候如果value == undefined,可能会导致validator里的value校验规则报jsError错误,因为没有try catch过,这个错误被吃掉,外部的form.validateFields也不会有任何反应。

  4. 经过getFieldDecorator注册过后的item,会丢失defaultValuevalue的属性,想要赋值预设值,必须通知getFieldDecorator时候传入option.initialValue进行预设值;

优化方案

使用antd的Form组件以及Form.Item来进行组件的包装和展示,表单管理采用外部库formik来控制,formik可以支持表单项的定义、展示、校验,formik本身暴露了api可以引入外部的校验库来做校验,官方推荐接入Yup来做检验管理。

formik本身是一个与view层无关的纯model层的表单库,我们可以将表单的校验结果与Form.Item结合,来控制错误提示。

Antd.Drawer

使用了antd的抽屉组件,想在抽屉展开时,调用接口动态加载数据。目前在抽屉组件<Drawer>里包裹了一个目录菜单组件<Tree>,然后在<Tree>组件内部通过副作用hook(useEffect)去发起请求。但是发现每次展开时,抽屉都会卡顿。请求的时间每次大概300ms左右。

看了github里,有人提了issue,但是问题并没有被解决就被关闭了。有个人提出了一个治标不治本的方案,如下:
解决方案
我通过使用一个hook来控制,使得在drawer动画完成后才显示容器内的内容,hook的代码如下:

/**
 * Drawer 可见性
 */
export const useDrawerVisible = timeout => {
  /** drawer 可见性 */
  const [visible, setVisible] = useState(false);
  /** 内容可见性 */
  const [contentVisible, setContentVisible] = useState(false);
  const open = () => {
    setVisible(true);
    setTimeout(() => setContentVisible(true), timeout);
  };
  const close = () => {
    setVisible(false);
    setContentVisible(false);
  };
  return {drawerVisible: visible, contentVisible, open, close};
};


const DrawerButton = () => {
  /** 抽屉可见性 */
  const {drawerVisible, contentVisible, open, close} = useDrawerVisible(350);

  return (
      <div>
        <a onClick={open}>
          点击显示Drawer
        </a>
        <Drawer
            width="700px"
            visible={drawerVisible}
            onClose={close}
        >
          {contentVisible &&
          <div>
            Drawer容器内的内容
          </div>}
        </Drawer>
      </div>
  );
};

这里的 timeout 设置为 350ms 是我猜想 Drawer 的动画时间应该在 350ms 左右

Antd.Layout

Layout下有Layout.Sider,layout本身有个props叫hasSIder: boolean。

// Layout.tsx
const classString = classNames(
    prefixCls,
    {
      [`${prefixCls}-has-sider`]: typeof hasSider === 'boolean' ? hasSider : siders.length > 0,
      [`${prefixCls}-rtl`]: direction === 'rtl',
    },
    className,
  );

// 对应的样式
 &&-has-sider {
    flex-direction: row;
    > .@{layout-prefix-cls},
    > .@{layout-prefix-cls}-content {
      overflow-x: hidden;
    }
  }

${prefixCls}-has-sider这个class的出现与否由hasSider 和siders决定,siders的addSider和removeSider事件是在layout的context里取的。

// Layout.tsx
 <LayoutContext.Provider
      value={{
        siderHook: {
          addSider: (id: string) => {
            setSiders(prev => [...prev, id]);
          },
          removeSider: (id: string) => {
            setSiders(prev => prev.filter(currentId => currentId !== id));
          },
        },
      }}
    >
      <Tag className={classString} {...others}>
        {children}
      </Tag>
    </LayoutContext.Provider>

所以当sider外部没有报过layout的时候,切换页面时候,sider的removeSider事件触发失败,导致${prefixCls}-has-siderclass的计算出问题,进而影响了css样式。

表现为:
在A页面左右布局正常,到了B页面可能有sider外部没有layout,本来的左右布局混乱了变成了上下布局。但是切回A页面后,依旧不能正常左右,还展示了错误的上下。

解决方法:
给sider的外部套上layout。

<Layout>
    <Layout.Sider theme="light" width="160">
        <LayoutMenu />
    </Layout.Sider>
    <Content />
</Layout>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352