ant-design icon indicating copy to clipboard operation
ant-design copied to clipboard

[Input] Cannot listen onBlur when Form set validateTrigger to "onBlur"

Open ah-peplink opened this issue 3 years ago • 12 comments

  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

Reproduction link

Edit on CodeSandbox

Steps to reproduce

  • Set validateTrigger="onBlur" in Form
  • listen onBlur event in Input

What is expected?

onBlur event handler should be fired

What is actually happening?

onBlur event handler not fired

Environment Info
antd 4.9.3
React 16.14.0
System Windows 10
Browser Chrome 87

ah-peplink avatar Dec 16 '20 03:12 ah-peplink

I am trying to fix this problem

AnathanPham avatar Dec 22 '20 03:12 AnathanPham

我找到了一个可行的解决办法。并在本地已经验证。

问题分析及解决方案

rc-filed-formnpm包中的Field组件在getControlled方法中代理了ant-design中的FormItem组件的children的事件。 Field组件代理事件需要获取ant-design中的FormItem组件的children.props才能确保安全的代理。

Field组件 对于render props类型的children处理时,调用getControlled没有传递childProps,所以此时Field组件无法获得FormItem组件的children.props。因此代理事件后,会将FormItem组件的children的事件进行覆盖。

// Field.tsx
  public getOnlyChild = (
    children:
  )=> {
    //...
    if (typeof children === 'function') {
      const meta = this.getMeta();

      return {
        ...this.getOnlyChild(children(this.getControlled(),// 在这里可以看到 getControlled 没有接收 childProps 作为参数,因为实际上也拿不到
          meta, this.props.fieldContext)),
        isFunction: true,
      };
    }
   //...
  };

所以解决问题的思路是:当Field组件的children为函数时,FormItem组件的children.props传递给Field组件(作为Fieldprops.originChildProps),在Field组件中接收originChildProps。将上述函数改为

  // Field.tsx
  public getOnlyChild = (
    children:
  )=> {
    //...
    if (typeof children === 'function') {
      const meta = this.getMeta();

      return {
        ...this.getOnlyChild(children(this.getControlled(this.props.originChildProps),// 此时能够安全的代理父组件的children的事件
          meta, this.props.fieldContext)),
        isFunction: true,
      };
    }
   //...
  };
// FormItem.tsx
function FormItem(props){
    <Field
      {...props}
      originChildProps={isValidElement(children) ? children.props : undefined}
      messageVariables={variables}
      /* TODO:这里的trigger默认值为onChange */
      trigger={trigger}
      validateTrigger={mergedValidateTrigger}
      onReset={() => {
        setDomErrorVisible(false);
      }}
    >
        {/* ... */}
    </Field>
}

@afc163 因为涉及两个仓库,我不清楚如何提交合并请求。因此我希望antd团队能够解决这个问题。

AnathanPham avatar Dec 22 '20 06:12 AnathanPham

先给rc-filed-form提PR,通过后发minor版本,然后给antd的feature分支发PR,升级rc-filed-form为该minor版本并调整其他代码,

yoyo837 avatar Dec 22 '20 06:12 yoyo837

先给rc-filed-form提PR,通过后发minor版本,然后给antd的feature分支发PR,升级rc-filed-form为该minor版本并调整其他代码,

好的,我尝试继续解决。

AnathanPham avatar Dec 22 '20 06:12 AnathanPham

hey how about the progress? I am still facing the problem using antd 4.8, which verison should work?

BR

jiawang1 avatar Aug 24 '21 23:08 jiawang1

快一年了,这个问题

orient-i avatar Nov 03 '21 04:11 orient-i

现在问题还是没有解决吗?这效率

mtiger95 avatar Mar 08 '22 03:03 mtiger95

这个问题现在看已经解决了

orient-i avatar Apr 13 '22 03:04 orient-i

目前看还没有解决?

weiChow avatar Jul 14 '22 16:07 weiChow

两年了,还没有解决?

huarse avatar Oct 11 '22 11:10 huarse

这是来自QQ邮箱的假期自动回复邮件。您好,我最近正在休假中,无法亲自回复您的邮件。我将在假期结束后,尽快给您回复。

weiChow avatar Oct 11 '22 11:10 weiChow

it works in "antd": "4.17.4"

young717 avatar Dec 13 '22 04:12 young717

Close since already worked in latest 4.x version: https://codesandbox.io/s/dynamic-rules-antd-4-9-3-forked-kjh9tr?file=/index.js

zombieJ avatar Mar 27 '23 16:03 zombieJ

这是来自QQ邮箱的假期自动回复邮件。您好,我最近正在休假中,无法亲自回复您的邮件。我将在假期结束后,尽快给您回复。

weiChow avatar Mar 27 '23 16:03 weiChow