处理用户的输入
function App() {
const [username, setUsername] = useState("");
const [list, setList] = useState([]);
function handleUsernameOnChange(e) {
setUsername(e.target.value);
}
function handleReset() {
setUsername("");
}
function handlePublish() {
setList([...list, username]);
setUsername("");
}
return (
<div className="App">
<ul>
{list.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
<div>
<label>username</label>
<input
type="text"
onChange={(e) => handleUsernameOnChange(e)}
value={username}
/>
</div>
<button onClick={handlePublish}>publish</button>
<button onClick={handleReset}>reset</button>
</div>
);
}
function App() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [repeatPassword, setRepeatPassword] = useState("");
const [gender, setGender] = useState("");
const [occupation, setOccupation] = useState("");
const [hobbies, setHobbies] = useState([]);
function handleHobbiesChange(e) {
const { value, checked } = e.target;
if (checked) {
setHobbies([...hobbies, value]);
} else {
setHobbies(hobbies.filter((hobby) => hobby !== value));
}
}
return (
<div className="App">
<form>
<label htmlFor="username">username</label>
<input
id="username"
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<label htmlFor="password">password</label>
<input
id="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<label htmlFor="repeatPassword">repeat password</label>
<input
id="repeatPassword"
type="password"
value={repeatPassword}
onChange={(e) => setRepeatPassword(e.target.value)}
/>
<label htmlFor="gender">gender</label>
<fieldset id="gender">
<input
type="radio"
name="gender"
value="male"
id="male"
checked={gender === "male"}
onChange={(e) => setGender(e.target.value)}
/>
<label htmlFor="male">man</label>
<input
type="radio"
name="gender"
value="female"
id="female"
checked={gender === "female"}
onChange={(e) => setGender(e.target.value)}
/>
<label htmlFor="female">woman</label>
</fieldset>
<label htmlFor="occupation">occupation</label>
<select id="occupation" onChange={(e) => setOccupation(e.target.value)}>
<option value="student">student</option>
<option value="teacher">teacher</option>
<option value="engineer">engineer</option>
</select>
<label htmlFor="hobbies">hobbies</label>
<fieldset id="hobbies">
<input
type="checkbox"
name="hobby"
id="programming"
value="programming"
checked={hobbies.includes("programming")}
onChange={handleHobbiesChange}
/>
<label htmlFor="programming">programming</label>
<input
type="checkbox"
name="hobby"
id="paint"
value="paint"
checked={hobbies.includes("paint")}
onChange={handleHobbiesChange}
/>
<label htmlFor="paint">paint</label>
<input
type="checkbox"
name="hobby"
id="music"
value="music"
checked={hobbies.includes("music")}
onChange={handleHobbiesChange}
/>
<label htmlFor="music">music</label>
</fieldset>
</form>
<ul>
<li>username: {username}</li>
<li>password: {password}</li>
<li>repeat password: {repeatPassword}</li>
<li>gender: {gender}</li>
<li>occupation: {occupation}</li>
<li>hobbies: {hobbies.join(", ")}</li>
</ul>
</div>
);
}
将状态写成对象形式、集成tailwindcss、处理表单提交和重置
function App() {
const initialUser = {
username: "",
password: "",
repeatPassword: "",
gender: "",
occupation: "",
hobbies: [],
};
const [user, setUser] = useState(initialUser);
function handleFormReset(e) {
e.preventDefault();
setUser(initialUser);
}
function handleFormSubmit(e) {
e.preventDefault();
console.log(user);
}
function handleHobbiesChange(e) {
const { value, checked } = e.target;
if (checked) {
setUser((prevUser) => ({
...prevUser,
hobbies: [...prevUser.hobbies, value],
}));
} else {
setUser((prevUser) => ({
...prevUser,
hobbies: prevUser.hobbies.filter((hobby) => hobby !== value),
}));
}
}
return (
<div className="container mx-auto h-screen px-4 flex flex-col items-center justify-center gap-y-2.5">
<form
className="w-3/5 border-2 p-8"
onReset={handleFormReset}
onSubmit={handleFormSubmit}
>
<label
className="block text-lg font-medium tracking-wide text-slate-600"
htmlFor="username"
>
username
</label>
<input
className="w-96 border-2 border-gray-300 p-2 text-lg outline-none"
id="username"
type="text"
value={user.username}
onChange={(e) => setUser({ ...user, username: e.target.value })}
/>
<label
className="block text-lg font-medium tracking-wide text-slate-600"
htmlFor="password"
>
password
</label>
<input
className="w-96 border-2 border-gray-300 p-2 text-lg outline-none"
id="password"
type="password"
value={user.password}
onChange={(e) => setUser({ ...user, password: e.target.value })}
/>
<label
className="block text-lg font-medium tracking-wide text-slate-600"
htmlFor="repeatPassword"
>
repeat password
</label>
<input
className="w-96 border-2 border-gray-300 p-2 text-lg outline-none"
id="repeatPassword"
type="password"
value={user.repeatPassword}
onChange={(e) => setUser({ ...user, repeatPassword: e.target.value })}
/>
<label className="block text-lg font-medium tracking-wide text-slate-600">
gender
</label>
<fieldset className="flex space-x-1" id="gender">
<input
type="radio"
name="gender"
value="male"
id="male"
checked={user.gender === "male"}
onChange={(e) => setUser({ ...user, gender: e.target.value })}
/>
<label
className="text-lg font-medium tracking-wide text-slate-600"
htmlFor="male"
>
man
</label>
<input
type="radio"
name="gender"
value="female"
id="female"
checked={user.gender === "female"}
onChange={(e) => setUser({ ...user, gender: e.target.value })}
/>
<label
className="text-lg font-medium tracking-wide text-slate-600"
htmlFor="female"
>
woman
</label>
</fieldset>
<label
className="block text-lg font-medium tracking-wide text-slate-600"
htmlFor="occupation"
>
occupation
</label>
<select
className="border-2 p-1 text-md outline-none"
id="occupation"
onChange={(e) => setUser({ ...user, occupation: e.target.value })}
>
<option value="student">student</option>
<option value="teacher">teacher</option>
<option value="engineer">engineer</option>
</select>
<label className="block text-lg font-medium tracking-wide text-slate-600">
hobbies
</label>
<fieldset className="flex gap-1" id="hobbies">
<input
type="checkbox"
name="hobby"
id="programming"
value="programming"
checked={user.hobbies.includes("programming")}
onChange={handleHobbiesChange}
/>
<label
className="leading-4 select-none text-lg font-medium tracking-wide text-slate-600"
htmlFor="programming"
>
programming
</label>
<input
type="checkbox"
name="hobby"
id="paint"
value="paint"
checked={user.hobbies.includes("paint")}
onChange={handleHobbiesChange}
/>
<label
className="leading-4 select-none text-lg font-medium tracking-wide text-slate-600"
htmlFor="paint"
>
paint
</label>
<input
type="checkbox"
name="hobby"
id="music"
value="music"
checked={user.hobbies.includes("music")}
onChange={handleHobbiesChange}
/>
<label
className="leading-4 select-none text-lg font-medium tracking-wide text-slate-600"
htmlFor="music"
>
music
</label>
</fieldset>
<button
className="border-2 rounded-lg px-4 py-2 m-2 bg-blue-400 font-medium text-white hover:bg-blue-500 transition-colors duration-300 ease-in-out"
type="submit"
>
提交
</button>
<button
className="border-2 rounded-lg px-4 py-2 m-2 bg-blue-400 font-medium text-white hover:bg-blue-500 transition-colors duration-300 ease-in-out"
type="reset"
>
重置
</button>
</form>
<ul className="w-3/5 border-2 p-8">
<li>username: {user.username}</li>
<li>password: {user.password}</li>
<li>repeat password: {user.repeatPassword}</li>
<li>gender: {user.gender}</li>
<li>occupation: {user.occupation}</li>
<li>hobbies: {user.hobbies.join(", ")}</li>
</ul>
</div>
);
}
表单校验
import "./App.css";
import { useState } from "react";
function App() {
const initialUser = {
username: "",
password: "",
repeatPassword: "",
gender: "",
occupation: "",
hobbies: [],
};
const [user, setUser] = useState(initialUser);
const [errors, setErrors] = useState({});
const rules = {
username: (value) => {
if (value.length < 3 || value.length > 10) {
return "用户名长度应在3-20之间";
}
},
password: (value) => {
return /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/.test(
value
)
? ""
: "密码必须包含大小写字母和数字和字符,长度不少于8";
},
};
function handleFormReset(e) {
e.preventDefault();
setUser(initialUser);
}
function handleFormSubmit(e) {
e.preventDefault();
console.log(user);
}
function handleHobbiesChange(e) {
const { value, checked } = e.target;
if (checked) {
setUser((prevUser) => ({
...prevUser,
hobbies: [...prevUser.hobbies, value],
}));
} else {
setUser((prevUser) => ({
...prevUser,
hobbies: prevUser.hobbies.filter((hobby) => hobby !== value),
}));
}
}
function handleUsernameChange(e) {
const { value, name } = e.target;
const error = rules[name] && rules[name](value);
setUser((prevUser) => ({ ...prevUser, [name]: value }));
setErrors((prevErrors) => ({ ...prevErrors, [name]: error }));
}
function handlePasswordChange(e) {
const { value, name } = e.target;
const error = rules[name] && rules[name](value);
setUser((prevUser) => ({ ...prevUser, [name]: value }));
setErrors((prevErrors) => ({ ...prevErrors, [name]: error }));
}
return (
<div className="container mx-auto h-screen px-4 flex flex-col items-center justify-center gap-y-2.5">
<form
className="w-3/5 border-2 p-8"
onReset={handleFormReset}
onSubmit={handleFormSubmit}
>
<label
className="block text-lg font-medium tracking-wide text-slate-600"
htmlFor="username"
>
username
</label>
<input
className="w-96 border-2 border-gray-300 p-2 text-lg outline-none"
id="username"
type="text"
name="username"
value={user.username}
onChange={handleUsernameChange}
/>
{errors.username && (
<div className="text-red-500">{errors.username}</div>
)}
<label
className="block text-lg font-medium tracking-wide text-slate-600"
htmlFor="password"
>
password
</label>
<input
className="w-96 border-2 border-gray-300 p-2 text-lg outline-none"
id="password"
type="password"
name="password"
value={user.password}
onChange={handlePasswordChange}
/>
{errors.password && (
<div className="text-red-500">{errors.password}</div>
)}
<label
className="block text-lg font-medium tracking-wide text-slate-600"
htmlFor="repeatPassword"
>
repeat password
</label>
<input
className="w-96 border-2 border-gray-300 p-2 text-lg outline-none"
id="repeatPassword"
type="password"
value={user.repeatPassword}
onChange={(e) => setUser({ ...user, repeatPassword: e.target.value })}
/>
<label className="block text-lg font-medium tracking-wide text-slate-600">
gender
</label>
<fieldset className="flex space-x-1" id="gender">
<input
type="radio"
name="gender"
value="male"
id="male"
checked={user.gender === "male"}
onChange={(e) => setUser({ ...user, gender: e.target.value })}
/>
<label
className="text-lg font-medium tracking-wide text-slate-600"
htmlFor="male"
>
man
</label>
<input
type="radio"
name="gender"
value="female"
id="female"
checked={user.gender === "female"}
onChange={(e) => setUser({ ...user, gender: e.target.value })}
/>
<label
className="text-lg font-medium tracking-wide text-slate-600"
htmlFor="female"
>
woman
</label>
</fieldset>
<label
className="block text-lg font-medium tracking-wide text-slate-600"
htmlFor="occupation"
>
occupation
</label>
<select
className="border-2 p-1 text-md outline-none"
id="occupation"
onChange={(e) => setUser({ ...user, occupation: e.target.value })}
>
<option value="student">student</option>
<option value="teacher">teacher</option>
<option value="engineer">engineer</option>
</select>
<label className="block text-lg font-medium tracking-wide text-slate-600">
hobbies
</label>
<fieldset className="flex gap-1" id="hobbies">
<input
type="checkbox"
name="hobby"
id="programming"
value="programming"
checked={user.hobbies.includes("programming")}
onChange={handleHobbiesChange}
/>
<label
className="leading-4 select-none text-lg font-medium tracking-wide text-slate-600"
htmlFor="programming"
>
programming
</label>
<input
type="checkbox"
name="hobby"
id="paint"
value="paint"
checked={user.hobbies.includes("paint")}
onChange={handleHobbiesChange}
/>
<label
className="leading-4 select-none text-lg font-medium tracking-wide text-slate-600"
htmlFor="paint"
>
paint
</label>
<input
type="checkbox"
name="hobby"
id="music"
value="music"
checked={user.hobbies.includes("music")}
onChange={handleHobbiesChange}
/>
<label
className="leading-4 select-none text-lg font-medium tracking-wide text-slate-600"
htmlFor="music"
>
music
</label>
</fieldset>
<button
className="border-2 rounded-lg px-4 py-2 m-2 bg-blue-400 font-medium text-white hover:bg-blue-500 transition-colors duration-300 ease-in-out"
type="submit"
>
提交
</button>
<button
className="border-2 rounded-lg px-4 py-2 m-2 bg-blue-400 font-medium text-white hover:bg-blue-500 transition-colors duration-300 ease-in-out"
type="reset"
>
重置
</button>
</form>
<ul className="w-3/5 border-2 p-8">
<li>username: {user.username}</li>
<li>password: {user.password}</li>
<li>repeat password: {user.repeatPassword}</li>
<li>gender: {user.gender}</li>
<li>occupation: {user.occupation}</li>
<li>hobbies: {user.hobbies.join(", ")}</li>
</ul>
</div>
);
}
export default App;
最后成果

评论区