常见表单元素
label + input
function App() { const [inputState, setInputState] = useState([]); return ( <> <label htmlFor="username">username {inputState}</label> <input type="text" id="username" value={inputState} onChange={(e) => { setInputState(e.target.value); }} /> </> );}
select && //multiSelect
function App() { const optionList = ["Taipei", "Taichung", "Kaohsiung"]; const [selectState, setSelectState] = useState([]); return ( <> {selectState} <select name="" id="" value={selectState} /*+ multiple={true} */ onChange={(e) => { setSelectState(e.target.value); /*setSelectState( [...e.target.selectedOptions].map((option) => option.value) ); */ }} > <option value="Choose the area" disabled> Choose the area </option> {optionList.map((location) => { return ( <option value={location} key={location}> {location} </option> ); })} </select> </> );}
checkbox
function App() { const [check, setCheck] = useState(false); return ( <> <label htmlFor="isCheck">确认状态 {check.toString()}</label> <input type="checkbox" id="isCheck" onChange={(e) => { setCheck(e.target.checked); }} value={check} /> </> );}
checkList
function App() { const [checkList, setCheckList] = useState([]); const handleCheckList = (e) => { if (e.target.checked) { setCheckList([...checkList, e.target.value]); } else { setCheckList(checkList.filter((item) => item !== e.target.value)); } }; return ( <> <label htmlFor="checkList1">item1</label> <input type="checkbox" id="checkList1" name="like" value="item1" onChange={handleCheckList} /> <label htmlFor="checkList2">item2</label> <input type="checkbox" id="checkList2" name="like" value="item2" onChange={handleCheckList} /> <label htmlFor="checkList3">item3</label> <input type="checkbox" id="checkList3" name="like" value="item3" onChange={handleCheckList} /> </> );}
Form && Submit
function App() { const [formData, setFormData] = useState({ username: "test", password: "123321", isCheck: false, }); const handleInputChange = (e) => { const value = e.target.type === "checkbox" ? e.target.checked : e.target.value; const name = e.target.name; setFormData({ ...formData, [name]: value, }); }; const handleSubmit = (e) => { e.preventDefault(); console.log(formData); }; return ( <> <form action=""> <div className="mb-3"> <label htmlFor="username" className="form-label"> 帐号 </label> <input type="text" id="username" className="form-control" name="username" onChange={handleInputChange} value={formData.username} /> </div> <div className="mb-3"> <label htmlFor="password" className="form-label"> 密码 </label> <input type="text" id="password" className="form-control" name="password" onChange={handleInputChange} value={formData.password} /> </div> <div className="mb-3"> <label htmlFor="isCheck">确认状态</label> <input type="checkbox" id="isCheck" className="isCheck" name="isCheck" onChange={handleInputChange} value={formData.isCheck} /> </div> <button type="submit" className="btn btn-primary" onClick={handleSubmit} > 送出 </button> </form> </> );}
onKeyDown键盘触发搜寻
function App() { const [search, setSearch] = useState(); const formHandleSubmit = (e) => { e.preventDefault(); console.log("开始搜寻:", search); }; const enterHandleSubmit = (e) => { if (e.key === "Enter") { console.log("开始搜寻:", search); } }; return ( <> {/* Way1 */} <form onSubmit={formHandleSubmit}> <div className="mb-3"> <label htmlFor="search2" className="form-label"> Search </label> <input type="text" name="search" id="search2" className="form-control" /> </div> </form> {/* Way2 */} <label htmlFor="search1" className="form-label"> Search </label> <input type="search" id="search1" className="form-control" name="search" value={search} onChange={(e) => { setSearch(e.target.value); }} onKeyDown={enterHandleSubmit} /> </> );}
React hook form (useForm)
建立环境npm install react-hook-form
import { useForm } from "react-hook-form";function App() { const { register, handleSubmit } = useForm(); const onSubmit = (data) => { console.log(data); }; return ( <> <form action="" onSubmit={handleSubmit(onSubmit)}> <div> <label htmlFor="username" className="form-label"></label> <input type="text" name="username" id="username " defaultValue="Willy" {...register("username")} //'username'可在其他input换成email等其他data className="form-control" /> </div> <button type="submit" className="btn btn-primary"> 注册 </button> </form> </> );}
watch && useWatch
import { useForm } from "react-hook-form";function App() { const { register, handleSubmit, watch, setValue, control } = useForm({ defaultValues: { username: "Willy", }, }); const onSubmit = (data) => { console.log(data); }; //watch // useEffect(() => { // const subscription = watch((value, { name }) => { // console.log(value, { name }); // if (name === "like") { // setValue("username", "Will"); // } // }); // console.log(subscription); // return () => subscription.unsubscribe(); // }, [watch]); //差异:useWatch 子层元件更新 不影响父层render const watchForm = useWatch({ control, }); useEffect(() => { console.log(watchForm); }, [watchForm]); return ( <> <div> <form action="" onSubmit={handleSubmit(onSubmit)}> <div className="mb-3"> <label htmlFor="username" className="form-label"> Username </label> <input type="text" name="username" id="username" {...register("username")} className="form-control" /> </div> <div className="mb-3"> <label htmlFor="checkList1">item1</label> <input type="checkbox" name="like" id="checkList1" value="item1" {...register("like")} /> <label htmlFor="checkList2">item2</label> <input type="checkbox" name="like" id="checkList2" value="item2" {...register("like")} /> <label htmlFor="checkList3">item3</label> <input type="checkbox" name="like" id="checkList3" value="item3" {...register("like")} /> </div> <button type="submit" className="btn btn-primary"> Register </button> </form> </div> </> );}
Form验证 + 元件化
BS 验证样式
快速生成表单程式码(官方)
form验证方法
若未安装bs 先在terminal 输入npm i bootstrap
import { useForm } from "react-hook-form";import Checkbox from "./Checkbox";import Input from "./Input";function App() { const { register, formState: { errors }, handleSubmit, getValues, control, } = useForm({}); const onSubmit = (data) => console.log(data); console.log("errors:", errors); const checkbox = [ { id: "checkList1", checkboxText: "item1" }, { id: "checkList2", checkboxText: "item2" }, { id: "checkList3", checkboxText: "item3", rules: { //rules放第几个都行(或是全放也可) required: { value: true, message: "至少勾选一项", }, }, }, { id: "checkList4", checkboxText: "item4" }, { id: "checkList5", checkboxText: "item5" }, ]; return ( <> <div> <form action="" onSubmit={handleSubmit(onSubmit)}> <div className="mb-3"> <Input register={register} errors={errors} id="username" labelText="Username" type="text" rules={{ required: { value: true, message: "必填", }, }} /> </div> <div className="mb-3"> <Input register={register} errors={errors} id="email" labelText="Email" type="email" rules={{ required: { value: true, message: "必填", }, pattern: { value: /^\S+@\S+$/i, message: "格式错误", }, }} /> </div> <div className="mb-3"> <Input register={register} errors={errors} id="tel" labelText="Tel" type="tel" rules={{ required: { value: true, message: "必填", }, minLength: { value: 8, message: "至少8码", }, maxLength: { value: 12, message: "不超过12码", }, }} /> </div> <div className="mb-3"> {checkbox.map((checkbox, idx, arr) => ( <Checkbox key={checkbox.id} register={register} errors={errors} type="checkbox" name="like" id={checkbox.id} checkboxText={checkbox.checkboxText} rules={checkbox.rules} checkboxLen={arr.length} /> ))} </div> <button type="submit" className="btn btn-primary"> Submit </button> </form> </div> </> );}export default App;
//Input.jsx
/* eslint-disable react/prop-types */const Input = ({ register, errors, id, labelText, type, rules }) => { return ( <div className="mb-3"> <label htmlFor={id} className="form-label"> {labelText} </label> <input type={type} name={id} id={id} {...register(id, rules)} className={`form-control ${errors[id] && "is-invalid"}`} /> {errors[id] && ( <div className="invalid-feedback">{errors?.[id]?.message}</div> )} </div> );};export default Input;
//Checkbox.jsx
/* eslint-disable react/prop-types */const Checkbox = ({ register, errors, type, name, id, rules, checkboxText, checkboxLen,}) => { return ( <div className="form-check"> <input type={type} name={name} id={id} className={`form-check-input ${errors[name] && "is-invalid"}`} {...register(name, rules)} value={checkboxText} /> <label htmlFor={id} className="form-check-label"> {checkboxText} </label> {errors.like && id === `checkList${checkboxLen}` && ( <div className="invalid-feedback">{errors?.like?.message}</div> )} </div> );};export default Checkbox;
加上axios 取得县市地址