在Antd-Form 表单组件使用getValueFromEvent属性为当前表单域赋值

在Antd-Form 表单组件使用getValueFromEvent属性为当前表单域赋值

技术杂谈小彩虹2021-08-23 18:49:03220A+A-

目前项目中对表单的使用较多,最近遇到了一个问题,大致描述:在表单域的onChange组件中无法使用setFields重置当前表单域的值.

  1. 发现问题
class App extends React.Component {
  handleChange = e => {
    const val = e.target.value.toUpperCase();
    this.props.form.setFieldsValue({
      userName: val
    });
  };

  render() {
    const { getFieldDecorator } = this.props.form;

    return (
      <Form onSubmit={this.handleSubmit}>
        <Form.Item
          labelCol={{ span: 5 }}
          wrapperCol={{ span: 12 }}
          label="前缀"
        >
          {getFieldDecorator("userName")(
            <Input onChange={this.handleChange} />
          )}
        </Form.Item>
      </Form>
    );
  }
}

  1. 进行尝试:在onChange的回调函数中利用setTimeout(func,0)[1]进行异步赋值,类似情况出现在onChange回调中利用form.getFieldsValue无法实时取值时。rc-form表单组件是通过setState的方式,将表单项封装为受控组件。在onChange的回调方法中,我们可以通过e.target.value拿到最新的值,此时,rc-form组件自身的赋值方法中并无法拿到这个最新的值,所以,进行同步并刷新页面值时,会把我们主动调用setFieldsValue方法传入setState中的值覆盖掉,所以使用异步赋值的方法,可以解决我们这里出现的值覆盖情况。
class App extends React.Component {
   handleChange = e => {
    const val = e.target.value.toUpperCase();
    this.props.form.setFieldsValue({
      prefix: val,
      suffix: val + "2"
    });
  };

  render() {
    const { getFieldDecorator } = this.props.form;

    return (
      <Form onSubmit={this.handleSubmit}>
        <Form.Item {...formItemLayout} label="prefix">
          {getFieldDecorator("prefix")(<Input onChange={this.handleChange} />)}
        </Form.Item>
        <Form.Item {...formItemLayout} label="suffix">
          {getFieldDecorator("suffix")(<Input />)}
        </Form.Item>
      </Form>
    );
  }
}

  1. 较之更优的方法-使用option.getValueFromEvent,进行赋值,相比之下,它更优雅而且不会造成二次渲染。
参数 说明 类型 默认值
option.getValueFormEvent 可以把onChange的参数转化为控件的值(例如:Event) func(...args) e
class App extends React.Component {
  render() {
    const { getFieldDecorator } = this.props.form;
    const varsPrefixField = getFieldDecorator("prefix", {
      getValueFromEvent: e => e.target.value.toUpperCase()
    });
    return (
      <Form onSubmit={this.handleSubmit}>
        <Form.Item {...formItemLayout}
          label="前缀"
        >
          {varsPrefixField(<Input />)}
        </Form.Item>
      </Form>
    );
  }
}


备注:这里的特殊情况出现在我们的表单域为自定义的InputGroup组合输入框。

Refrence:

[1] “如果以0毫秒的超时时间来调用setTimeout(),那么指定的函数不会立刻执行。相反,会把它放到队列中,等到前面处于等待状态的事件处理程序全部执行完成后,再“立即”调用它。”

摘录来自: (美)David Flanagan. “JavaScript权威指南(原书第6版)”。 iBooks.

点击这里复制本文地址 以上内容由权冠洲的博客整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!

支持Ctrl+Enter提交

联系我们| 本站介绍| 留言建议 | 交换友链 | 域名展示
本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除

权冠洲的博客 © All Rights Reserved.  Copyright quanguanzhou.top All Rights Reserved
苏公网安备 32030302000848号   苏ICP备20033101号-1
本网站由 提供CDN/云存储服务

联系我们