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;
相关推荐
mONESY1 小时前
ReAct 智能体循环与 JavaScript 异步并发原理深度解析
react.js
北辰alk12 小时前
Next.js 全栈开发指南:从项目初始化到生产环境部署
react.js
胡哈18 小时前
React Compiler:让开发者忘掉 memo 这件事
前端·react.js
光影少年21 小时前
react navite JSBridge 通信机制、异步通信特点
react native·react.js·掘金·金石计划
ndsc_d21 小时前
10分钟搭建B端SaaS数据看板:Paico+TDesign+React实战复盘
前端·人工智能·react.js·ui·前端框架·aigc·tdesign
我是大卫1 天前
React源码解析-第三部分:协调与提交
前端·react.js·源码
甜味弥漫1 天前
React 从类组件到 Hooks:为什么 Hooks 改变了 React?
前端·javascript·react.js
asdzx671 天前
在 React 中轻松实现 PDF 转 Word:纯前端 WASM 方案实战
前端·react.js·pdf
我是大卫2 天前
React源码解析-第一部分:宏观架构
前端·react.js·源码
我是大卫2 天前
React源码解析-第二部分:更新与调度
前端·react.js·源码