React 實(shí)現(xiàn)表單組件的示例代碼
表單是html的基礎(chǔ)元素,接下來(lái)我會(huì)用React實(shí)現(xiàn)一個(gè)表單組件。支持包括輸入狀態(tài)管理,表單驗(yàn)證,錯(cuò)誤信息展示,表單提交,動(dòng)態(tài)表單元素等功能。
數(shù)據(jù)狀態(tài)
表單元素的輸入狀態(tài)管理,可以基于react state 實(shí)現(xiàn)。
const [formData, setFormData] = useState(initial_data);
參數(shù)校驗(yàn)
在表單元素變更后,對(duì)變更結(jié)果進(jìn)行驗(yàn)證,若驗(yàn)證失敗,則更新失敗狀態(tài),若驗(yàn)證成功,則更新數(shù)據(jù)狀態(tài), 并移除之前老的失敗狀態(tài)。
/** * 表單錯(cuò)誤狀態(tài) */ const [errors, setErrors] = useState({}); /** * 表單數(shù)據(jù)變更處理函數(shù) */ const setFieldData = (name, value) => { // 進(jìn)行參數(shù)校驗(yàn) 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 }); }
表單提交
表單提交需要判斷是否有校驗(yàn)失敗錯(cuò)誤,如果有的話提交失敗,如果沒(méi)有提交成功。
/** * 表單提交處理函數(shù) */ const handleSubmit = (e) => { e.preventDefault(); if (errors && Object.keys(errors).length > 0) { console.log('表單校驗(yàn)未通過(guò)'); return; } if (submitFunc) { console.log('開始執(zhí)行提交函數(shù)'); submitFunc(formData); } }
表單項(xiàng)組件
表單項(xiàng)組件會(huì)根據(jù)參數(shù)不同的類型返回不同的組件,并且error和fieldData,setFieldData與父組件Form綁定。
/** * 表單項(xiàng)組件 */ 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實(shí)現(xiàn),并對(duì)表單form的功能進(jìn)行日常封裝。
import {useState} from "react"; /** * 表單組件 * @param initial_data 初始數(shù)據(jù) * @param validators 校驗(yàn)器 * @param submitFunc 提交函數(shù) * @param children FormItem組件列表 */ const Form = ({initial_data, validators, submitFunc, children}) => { /** * 表單數(shù)據(jù)狀態(tài) */ const [formData, setFormData] = useState(initial_data); /** * 表單錯(cuò)誤狀態(tài) */ const [errors, setErrors] = useState({}); /** * 表單數(shù)據(jù)變更處理函數(shù) */ const setFieldData = (name, value) => { // 進(jìn)行參數(shù)校驗(yàn) 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('表單校驗(yàn)未通過(guò)'); 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> </> ) } /** * 表單項(xiàng)組件 */ 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 '密碼長(zhǎng)度不能小于6'; } } }}> <FormItem name="username" label="用戶名" type='text'/> <FormItem name="password" label="密碼" type='password'/> <FormItem name="submit" label="提交" type='submit'/> </Form> </div>); }
到此這篇關(guān)于React 實(shí)現(xiàn)表單組件的示例代碼的文章就介紹到這了,更多相關(guān)React 表單組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
react-dnd實(shí)現(xiàn)任意拖動(dòng)與互換位置
這篇文章主要為大家詳細(xì)介紹了react-dnd實(shí)現(xiàn)任意拖動(dòng)與互換位置,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08React中使用dnd-kit實(shí)現(xiàn)拖曳排序功能
在這篇文章中,我將帶著大家一起探究React中使用dnd-kit實(shí)現(xiàn)拖曳排序功能,由于前陣子需要在開發(fā) Picals 的時(shí)候,需要實(shí)現(xiàn)一些拖動(dòng)排序的功能,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2024-06-06詳解如何用webpack4從零開始構(gòu)建react開發(fā)環(huán)境
這篇文章主要介紹了詳解如何用webpack4從零開始構(gòu)建react開發(fā)環(huán)境,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01比ant更豐富Modal組件功能實(shí)現(xiàn)示例詳解
這篇文章主要為大家介紹了比ant更豐富Modal組件功能實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11淺談React的React.FC與React.Component的使用
本文主要介紹了React的React.FC與React.Component的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09