在Antd-Form 表單組件使用getValueFromEvent屬性爲當前表單域賦值

目前項目中對錶單的使用較多,最近遇到了一個問題,大體描述:在表單域的onChange組件中沒法使用setFields重置當前表單域的值.bash

  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組合輸入框。app

Refrence:異步

[1] 「若是以0毫秒的超時時間來調用setTimeout(),那麼指定的函數不會馬上執行。相反,會把它放到隊列中,等到前面處於等待狀態的事件處理程序所有執行完成後,再「當即」調用它。」函數

摘錄來自: (美)David Flanagan. 「JavaScript權威指南(原書第6版)」。 iBooks.ui

相關文章
相關標籤/搜索