react-開發經驗分享-form表單組件中封裝一個單獨的input

Author:Mr.柳上原

  • 付出不亞於任何的努力
  • 願我們所有的努力,都不會被生活辜負
  • 不忘初心,方得始終

在form表單中自定義封裝一個input組件

如果不做處理

form表單提交時是獲取不到這個自定義組件的數據的

這個坑對於新手來說

真的是個大坑

特別是對錶單內的元素做提交不是很瞭解的人

用ant的ui框架來說明吧

一個基礎的表單

// ant表單組件
import { Form, Select, Input, Button } from 'antd';

const FormItem = Form.Item;
const Option = Select.Option;

class App extends React.Component {
  handleSubmit = (e) => {
    e.preventDefault();
    this.props.form.validateFields((err, values) => {
      if (!err) {
        console.log('Received values of form: ', values);
      }
    });
  }

  handleSelectChange = (value) => {
    console.log(value);
    this.props.form.setFieldsValue({
      note: `Hi, ${value === 'male' ? 'man' : 'lady'}!`,
    });
  }

  render() {
    const { getFieldDecorator } = this.props.form;
    return (
      <Form onSubmit={this.handleSubmit}>
        <FormItem
          label="Note"
          labelCol={{ span: 5 }}
          wrapperCol={{ span: 12 }}
        >
          {getFieldDecorator('note', {
            rules: [{ required: true, message: 'Please input your note!' }],
          })(
            <Input />
          )}
        </FormItem>
        <FormItem
          label="Gender"
          labelCol={{ span: 5 }}
          wrapperCol={{ span: 12 }}
        >
          {getFieldDecorator('gender', {
            rules: [{ required: true, message: 'Please select your gender!' }],
          })(
            <Select
              placeholder="Select a option and change input text above"
              onChange={this.handleSelectChange}
            >
              <Option value="male">male</Option>
              <Option value="female">female</Option>
            </Select>
          )}
        </FormItem>
        <FormItem
          wrapperCol={{ span: 12, offset: 5 }}
        >
          <Button type="primary" htmlType="submit">
            Submit
          </Button>
        </FormItem>
      </Form>
    );
  }
}

App = Form.create({})(App);
export default App;

如果我們要自定義Select組件
在組件內部做後端數據請求
並渲染到子元素Option裏
那麼我們就需要從新封裝自定義這個原生的Select組件

// 把Select單獨提取出來
import React, { Component } from 'react';
import { Select, Icon } from 'antd';

import initialApi from './services/initialApi'; // 封裝的後端接口請求

class SelectForm extends React.Component {
  constructor(props) {
    super(props);

    const value = props.value || {};
    this.state = {
      staffList: [], // 列表
    }
  }

  // 獲焦時查詢後端數據
  onFocus = () => {
    this.onRequstStaffData(this.props.organizationId);
  }

  // 查詢數據
  onRequstStaffData = async (inquireId) => {
    let staffInquireData = {
      organizationId: `${inquireId}`,
      isDeleted: false,
      pageIndex: 0,
      pageSize: 9,
    } // 請求體
    let staffData = await initialApi.postStaff(staffInquireData);
    let staffList = staffData.extension || [];
    
    this.setState({
      staffList,
    })
  }

  // Select 數據變化時讀取 value 值
  handleChange = (value) => {
    this.triggerChange(value);
  }

  // triggerChange 方法把獲取到的 value 值返回給父級 form 表單 
  triggerChange = (changedValue) => {
    const onChange = this.props.onChange;
    
    if(onChange) {
      onChange(changedValue);
    }
  }

  render() {
    return (
      <Select style={{width: 200}} suffixIcon={<Icon type="team" style={{color: 'rgba(0, 0, 0, 0.38)'}} />} onChange={this.handleChange}
        defaultValue={`${this.props.user.profile.name}`} notFoundContent="沒有查詢到數據!" onFocus={this.onFocus}
      >
        <OptGroup label="Manager">
          {this.state.staffList.map((item, index) => {
            return (
              <Option key={item.id} value={item.trueName}>{item.trueName}</Option>
            )
          })}
        </OptGroup>
      </Select>
    )
  }
}

export default SelectForm;

並把這個自定義組件導入到原來的form表單裏

// 修改後的ant表單組件
import { Form, Select, Input, Button } from 'antd';
import SelectForm from './selectForm';

const FormItem = Form.Item;

class App extends React.Component {
  handleSubmit = (e) => {
    e.preventDefault();
    this.props.form.validateFields((err, values) => {
      if (!err) {
        console.log('Received values of form: ', values);
      }
    });
  }

  render() {
    const { getFieldDecorator } = this.props.form;
    return (
      <Form onSubmit={this.handleSubmit}>
        <FormItem
          label="Note"
          labelCol={{ span: 5 }}
          wrapperCol={{ span: 12 }}
        >
          {getFieldDecorator('note', {
            rules: [{ required: true, message: 'Please input your note!' }],
          })(
            <Input />
          )}
        </FormItem>
        <FormItem
          label="Gender"
          labelCol={{ span: 5 }}
          wrapperCol={{ span: 12 }}
        >
          {getFieldDecorator('gender', {
            rules: [{ required: true, message: 'Please select your gender!' }],
          })(
            <SelectForm organizationId={'傳給SelectForm的值'} user={'傳給SelectForm的值'} />
          )}
        </FormItem>
        <FormItem
          wrapperCol={{ span: 12, offset: 5 }}
        >
          <Button type="primary" htmlType="submit">
            Submit
          </Button>
        </FormItem>
      </Form>
    );
  }
}

const WrappedApp = Form.create()(App);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章