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