React 实现表单组件的示例代码

 更新时间:2024年07月09日 09:13:04   作者:卡卡舅舅  
本文主要介绍了React 实现表单组件的示例代码,支持包括输入状态管理,表单验证,错误信息展示,表单提交,动态表单元素等功能,具有一定的参考价值,感兴趣的可以了解一下

表单是html的基础元素,接下来我会用React实现一个表单组件。支持包括输入状态管理,表单验证,错误信息展示,表单提交,动态表单元素等功能。

数据状态

表单元素的输入状态管理,可以基于react state 实现。

const [formData, setFormData] = useState(initial_data);

 参数校验     

在表单元素变更后,对变更结果进行验证,若验证失败,则更新失败状态,若验证成功,则更新数据状态, 并移除之前老的失败状态。

/**
 * 表单错误状态
 */
const [errors, setErrors] = useState({});


/**
 * 表单数据变更处理函数
 */
const setFieldData = (name, value) => {
    // 进行参数校验
    if (validators && validators[name]) {
        const error = validators[name](value);
        if (error) {
            setErrors((errors) => ({...errors, [name]: error}));
            return;
        }

        setErrors((errors) => {
            const newErrors = {...errors};
            delete newErrors[name];
            return newErrors;
        })
    }


    // 更新表单数据
    setFormData({
        ...formData,
        [name]: value
    });
}

表单提交

表单提交需要判断是否有校验失败错误,如果有的话提交失败,如果没有提交成功。

/**
 * 表单提交处理函数
 */
const handleSubmit = (e) => {
    e.preventDefault();
    if (errors && Object.keys(errors).length > 0) {
        console.log('表单校验未通过');
        return;
    }
    if (submitFunc) {
        console.log('开始执行提交函数');
        submitFunc(formData);
    }
}

表单项组件

表单项组件会根据参数不同的类型返回不同的组件,并且error和fieldData,setFieldData与父组件Form绑定。

/**
 * 表单项组件
 */
const FormItem = ({name, type, error, label, fieldData, setFieldData}) => {
    if (type === 'submit') {
        return (
            <div>
                <input type="submit" value={label}/>
            </div>
        )
    } else if (type === 'text') {
        return (
            <div>
                <label htmlFor={name}>{label}</label>
                <input type="text" name={name} value={fieldData} onChange={e => setFieldData(name, e.target.value)}/>
                {error && <span>{error}</span>}
            </div>
        )
    } else if (type === 'password') {
        return (
            <div>
                <label htmlFor={name}>{label}</label>
                <input type="password" name={name} value={fieldData}
                       onChange={e => setFieldData(name, e.target.value)}/>
                {error && <span>{error}</span>}
            </div>)
    }
    return null;
}

组件整体代码

Form组件是基于React实现,并对表单form的功能进行日常封装。

import {useState} from "react";

/**
 * 表单组件
 * @param initial_data 初始数据
 * @param validators 校验器
 * @param submitFunc 提交函数
 * @param children FormItem组件列表
 */
const Form = ({initial_data, validators, submitFunc, children}) => {
    /**
     * 表单数据状态
     */
    const [formData, setFormData] = useState(initial_data);

    /**
     * 表单错误状态
     */
    const [errors, setErrors] = useState({});


    /**
     * 表单数据变更处理函数
     */
    const setFieldData = (name, value) => {
        // 进行参数校验
        if (validators && validators[name]) {
            const error = validators[name](value);
            if (error) {
                setErrors((errors) => ({...errors, [name]: error}));
                return;
            }

            setErrors((errors) => {
                const newErrors = {...errors};
                delete newErrors[name];
                return newErrors;
            })
        }


        // 更新表单数据
        setFormData({
            ...formData,
            [name]: value
        });
    }

    /**
     * 表单提交处理函数
     */
    const handleSubmit = (e) => {
        e.preventDefault();
        if (errors && Object.keys(errors).length > 0) {
            console.log('表单校验未通过');
            return;
        }
        if (submitFunc) {
            console.log('开始执行提交函数');
            submitFunc(formData);
        }
    }

    return (
        <>
            <div>
                <form onSubmit={handleSubmit}>
                    {
                        children.map((child, index) => {
                            return (
                                <FormItem
                                    key={index}
                                    name={child.props.name}
                                    label={child.props.label}
                                    error={errors[child.props.name]}
                                    type={child.props.type}
                                    fieldData = {fromData.[child.props.name]}
                                    setFieldData={setFieldData}
                                >
                                    {child}
                                </FormItem>
                            )
                        })
                    }
                </form>
            </div>
        </>
    )
}

/**
 * 表单项组件
 */
const FormItem = ({name, type, error, label, fieldData, setFieldData}) => {
    if (type === 'submit') {
        return (
            <div>
                <input type="submit" value={label}/>
            </div>
        )
    } else if (type === 'text') {
        return (
            <div>
                <label htmlFor={name}>{label}</label>
                <input type="text" name={name} value={fieldData} onChange={e => setFieldData(name, e.target.value)}/>
                {error && <span>{error}</span>}
            </div>
        )
    } else if (type === 'password') {
        return (
            <div>
                <label htmlFor={name}>{label}</label>
                <input type="password" name={name} value={fieldData}
                       onChange={e => setFieldData(name, e.target.value)}/>
                {error && <span>{error}</span>}
            </div>)
    }
    return null;
}

export {Form, FormItem};

使用样例

效果图见下图,使用样例代码见下方代码。        

function App() {
    return (<div>
        <Form submitFunc={(data) => console.log(data)} initial_data={{username: 'vicyor', password: '123456'}}
              validators={{
                  password: (val) => {
                      if (val.length < 6) {
                          return '密码长度不能小于6';
                      }
                  }
              }}>
            <FormItem name="username" label="用户名" type='text'/>
            <FormItem name="password" label="密码" type='password'/>
            <FormItem name="submit" label="提交" type='submit'/>
        </Form>
    </div>);
}

 到此这篇关于React 实现表单组件的示例代码的文章就介绍到这了,更多相关React 表单组件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • React Hooks useReducer 逃避deps组件渲染次数增加陷阱

    React Hooks useReducer 逃避deps组件渲染次数增加陷阱

    这篇文章主要介绍了React Hooks 之 useReducer 逃避deps后增加组件渲染次数的陷阱详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • 前端框架react-spring基础用法

    前端框架react-spring基础用法

    这篇文章主要为大家介绍了前端框架react-spring基础用法示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • React 中的重新渲染类组件及函数组件

    React 中的重新渲染类组件及函数组件

    这篇文章主要为大家介绍了React 中的重新渲染类组件及函数组件使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • React 时间切片理解分析

    React 时间切片理解分析

    这篇文章主要为大家介绍了React 时间切片理解分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • React 组件中的 bind(this)示例代码

    React 组件中的 bind(this)示例代码

    这篇文章主要介绍了 React 组件中的 bind(this) ,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-09-09
  • React 组件传 children 的各种案例方案详解

    React 组件传 children 的各种案例方案详解

    自定义组件的时候往往需要传 children,由于写法比较多样,我就总结了一下,要自定义的组件其中包含一个 title 和一个 children,本文通过实例代码给大家介绍的非常详细,需要的朋友参考下吧
    2023-10-10
  • React Hook useState useEffect componentDidMount componentDidUpdate componentWillUnmount问题

    React Hook useState useEffect componentD

    这篇文章主要介绍了React Hook useState useEffect componentDidMount componentDidUpdate componentWillUnmount问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • react中的ajax封装实例详解

    react中的ajax封装实例详解

    这篇文章主要介绍了react中的ajax封装实例详解的相关资料,希望通过本文能帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下
    2017-10-10
  • JavaScript React如何修改默认端口号方法详解

    JavaScript React如何修改默认端口号方法详解

    这篇文章主要介绍了JavaScript React如何修改默认端口号方法详解,文中通过步骤图片解析介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • React使用useImperativeHandle自定义暴露给父组件的示例详解

    React使用useImperativeHandle自定义暴露给父组件的示例详解

    useImperativeHandle 是 React 提供的一个自定义 Hook,用于在函数组件中显式地暴露给父组件特定实例的方法,本文将介绍 useImperativeHandle的基本用法、常见应用场景,需要的可以参考下
    2024-03-03

最新评论