React 表单组件实现

一、介绍

        本文将会基于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;

相关推荐

  1. React - 组件实现

    2023-12-07 12:02:02       39 阅读
  2. React 组件实现

    2023-12-07 12:02:02       41 阅读
  3. ReactReact组件

    2023-12-07 12:02:02       20 阅读
  4. React 、处理受控组件、非受控组件

    2023-12-07 12:02:02       28 阅读
  5. React 中重新实现强制实施

    2023-12-07 12:02:02       15 阅读
  6. React

    2023-12-07 12:02:02       13 阅读
  7. 使用formio和react实现在线设计

    2023-12-07 12:02:02       13 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-07 12:02:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-07 12:02:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-07 12:02:02       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-07 12:02:02       20 阅读

热门阅读

  1. 五花八门客户问题(BUG) - 数据库索引损坏

    2023-12-07 12:02:02       47 阅读
  2. Metasploit的安全防御和逃逸

    2023-12-07 12:02:02       25 阅读
  3. SELinux refpolicy详解(9)

    2023-12-07 12:02:02       55 阅读
  4. Metasploit的漏洞挖掘和利用

    2023-12-07 12:02:02       26 阅读
  5. 详解ES6中的symbol

    2023-12-07 12:02:02       31 阅读
  6. Shopify 开源 WebAssembly 工具链 Ruvy

    2023-12-07 12:02:02       36 阅读
  7. Qt对象树与所有权管理

    2023-12-07 12:02:02       40 阅读
  8. 51单片机程序

    2023-12-07 12:02:02       36 阅读
  9. uniapp-获取手机型号

    2023-12-07 12:02:02       39 阅读
  10. 网页产品经理常用的ChatGPT通用提示词模板

    2023-12-07 12:02:02       48 阅读
  11. 27、数据存储&秒表(定时器扫描按键数码管)

    2023-12-07 12:02:02       36 阅读
  12. 【C++】时间time库

    2023-12-07 12:02:02       43 阅读
  13. 【力扣100】2.字母异位词分组

    2023-12-07 12:02:02       41 阅读