React 表单组件实现

一、介绍

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

二、使用教程

1.表单提交功能

javascript 复制代码
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

javascript 复制代码
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

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

    ]
}

b. 自定义表单组件

javascript 复制代码
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能力

javascript 复制代码
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学习教程,从入门到精通,React AJAX 语法知识点与案例详解(18)
前端·javascript·vue.js·学习·react.js·ajax·vue3
NeverSettle_1 天前
React工程实践面试题深度分析2025
javascript·react.js
学前端搞口饭吃1 天前
react reducx的使用
前端·react.js·前端框架
努力往上爬de蜗牛1 天前
react3面试题
javascript·react.js·面试
开心不就得了1 天前
React 进阶
前端·javascript·react.js
谢尔登1 天前
【React】React 哲学
前端·react.js·前端框架
学前端搞口饭吃1 天前
react context如何使用
前端·javascript·react.js
GDAL1 天前
为什么Cesium不使用vue或者react,而是 保留 Knockout
前端·vue.js·react.js
Dragon Wu2 天前
React state在setInterval里未获取最新值的问题
前端·javascript·react.js·前端框架
YU大宗师2 天前
React面试题
前端·javascript·react.js