一、介绍

        本文将会基于react实现表单的功能,包括表单提交和跳转、表单验证、动态表单元素、动态内容加载。

二、使用教程

1.表单提交功能

export default class FormSubmit extends React.PureComponent{
    
    state = {
        name: ""
    }

    handleNameChange = evt => {
        this.setState({
            name: evt.target.value
        });

    }

    handleSubmit = evt => {
        evt.preventDefault(); // 阻止默认事件
        if (!this.state.name){
            this.setState({error: "Name is required"});
            return;
        }
        fetchUserList(this.state.name);        
    }
    
    const {userState, fetchUserList} = useFetchUserList();

    render(){
        return (
            <>
            <form className = "comment-box" onSubmit = {this.handleSubmit}>
                <div>
                    <label>Name:</label> 
                    <input value = {this.state.name} onchange = {this.handleNameChange}/>
                </div>
                {userState.error && <span>userstate.error</span>}
                <div>
                    <button>Submit</button>
                </div>
            </form>
            {userState.data && <ul>userState.data.map((user)=> <li>user.name</li>)</ul>}
            </>
        )    
    
    }


    

}

user-service.js

export const userFetchUserList = () => {
    const initialState = {data:[], isLoading:false, error:null};

  // reducer
  function reducer(state, action){
    switch (action.type){
        case FETCH_USER_LIST_BEGIN:
            return (data:[action.res.data], isLoading: true, error:null);
        case FETCH_USER_LIST_SUCCESS:
            return (...state, isLoading: false, error:null);
        case FETCH_USER_LIST_ERROR:
            return (...state, isLoading: false, 
                    error:res.data.error);
    
    }
    
  }

  const [state, dispatch] = useReducer(reducer, initialState);

  function fetchUserList(){

     dispatch({type: FETCH_USER_LIST_BEGIN});    
     
     const doRequest = axios.get("http://www.user.com/user/list");
     doRequest.then(
                res => {
                    dispatch({
                        type: FETCH_USER_LIST_BEGIN,
                        data: res.data
                    });
                },
                err => {
                    dispatch({
                        type: FETCH_USER_LIST_ERROR,
                        data: {error:err}
                        }
                    );
          
                }
            );
   }
    
    return {state, fetchUserList};
}

2.动态表单元素 

a.定义meta

const formMeta = {
    colon: true,
    columns:1,
    elements: [
        {
            key: "userName",
            label: "User name",
            tooltip: "user name",
            widget: Input,
            required: true
        }

    ]
}

b. 自定义表单组件

const CustomForm = ({meta}) => {
    
    function renderFormItem = (item) => {
        const { widget: WidgetComponent, key, label, tooltip, required } = item;
        return (
          <Form.Item
            key={key}
            label={
              <span>
                {label}
                {tooltip && <Tooltip title={tooltip}></Tooltip>}
              </span>
            }
            name={key}
            rules={[{ required, message: `Please input your ${label}!` }]}
          >
            <WidgetComponent placeholder={`Please input your ${label}`} />
          </Form.Item>
        );        
    }


   const renderFormItems = () => {
        if (meta && meta.elements) {
          return meta.elements.map((item) => renderFormItem(item));
        }
        return null;
      };    


   return (
    <Form
      form={form}
      name="custom_form"
      onFinish={onFinish}
      initialValues={formData}
      labelCol={{ span: meta.columns }}
      wrapperCol={{ span: meta.columns }}
    >
      {renderFormItems()}
      {{children}}
      <Form.Item>
        <Button type="primary" htmlType="submit">
          Submit
        </Button>
      </Form.Item>
    </Form>
  );
}

3.表单元素验证

   直接使用ant design提供的Form能力

import {Form, Input, Button} from 'antd';

const DemoForm = () => {
    const onFinish = (values) =>{
        console.log('Received values:', values);
    };
    
    const validateAge = (rule, age) => {
        if (age && age < 18){
            return Promise.reject('年龄必须大于18岁!');
        } 
        return Promise.resolve();
    }

    return (
        <Form name = "basic" onFinish = {onFinish}>
            <Form.Item label = "年龄" name = "age" 
                rules = {[{required:true, message:'请输入年龄!'},{validator: validateAge}]}   
            >
                <Input type = "number"/>
            </Form.Item>
        </Form>
    );
}

export default DemoForm;
12-07 11:55