React 實現(xiàn)表單組件的示例代碼
表單是html的基礎(chǔ)元素,接下來我會用React實現(xiàn)一個表單組件。支持包括輸入狀態(tài)管理,表單驗證,錯誤信息展示,表單提交,動態(tài)表單元素等功能。
數(shù)據(jù)狀態(tài)
表單元素的輸入狀態(tài)管理,可以基于react state 實現(xiàn)。
const [formData, setFormData] = useState(initial_data);
參數(shù)校驗
在表單元素變更后,對變更結(jié)果進行驗證,若驗證失敗,則更新失敗狀態(tài),若驗證成功,則更新數(shù)據(jù)狀態(tài), 并移除之前老的失敗狀態(tài)。
/**
* 表單錯誤狀態(tài)
*/
const [errors, setErrors] = useState({});
/**
* 表單數(shù)據(jù)變更處理函數(shù)
*/
const setFieldData = (name, value) => {
// 進行參數(shù)校驗
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;
})
}
// 更新表單數(shù)據(jù)
setFormData({
...formData,
[name]: value
});
}表單提交
表單提交需要判斷是否有校驗失敗錯誤,如果有的話提交失敗,如果沒有提交成功。
/**
* 表單提交處理函數(shù)
*/
const handleSubmit = (e) => {
e.preventDefault();
if (errors && Object.keys(errors).length > 0) {
console.log('表單校驗未通過');
return;
}
if (submitFunc) {
console.log('開始執(zhí)行提交函數(shù)');
submitFunc(formData);
}
}
表單項組件
表單項組件會根據(jù)參數(shù)不同的類型返回不同的組件,并且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實現(xiàn),并對表單form的功能進行日常封裝。
import {useState} from "react";
/**
* 表單組件
* @param initial_data 初始數(shù)據(jù)
* @param validators 校驗器
* @param submitFunc 提交函數(shù)
* @param children FormItem組件列表
*/
const Form = ({initial_data, validators, submitFunc, children}) => {
/**
* 表單數(shù)據(jù)狀態(tài)
*/
const [formData, setFormData] = useState(initial_data);
/**
* 表單錯誤狀態(tài)
*/
const [errors, setErrors] = useState({});
/**
* 表單數(shù)據(jù)變更處理函數(shù)
*/
const setFieldData = (name, value) => {
// 進行參數(shù)校驗
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;
})
}
// 更新表單數(shù)據(jù)
setFormData({
...formData,
[name]: value
});
}
/**
* 表單提交處理函數(shù)
*/
const handleSubmit = (e) => {
e.preventDefault();
if (errors && Object.keys(errors).length > 0) {
console.log('表單校驗未通過');
return;
}
if (submitFunc) {
console.log('開始執(zhí)行提交函數(shù)');
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>);
}到此這篇關(guān)于React 實現(xiàn)表單組件的示例代碼的文章就介紹到這了,更多相關(guān)React 表單組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解如何用webpack4從零開始構(gòu)建react開發(fā)環(huán)境
這篇文章主要介紹了詳解如何用webpack4從零開始構(gòu)建react開發(fā)環(huán)境,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-01-01
淺談React的React.FC與React.Component的使用
本文主要介紹了React的React.FC與React.Component的使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09

