>我正在创建一个注册表单,其中包含多个字段,名字,姓氏,电子邮件和密码:
法典:
class Sign Up extends Component {
state={
firstName: '',
lastName: '',
email: '',
password: '',
}
handleChange(e){
this.setState({
[e.target.id]: e.target.value
})
}
return (
<form onSubmit={handleSubmit}>
<h5>Sign Up</h5>
<div className="input-field">
<label htmlFor="firstName">First Name</label>
<input type="text" id="firstName" onChange={handleChange}/>
</div>
<div className="input-field">
<label htmlFor="lastName"></label>
<input type="text" id="lastName" onChange={handleChange}/ >
</div>
<div className="input-field">
<label htmlFor="email"></label>
<input type="email" onChange={handleChange} />
</div>
<div className="input-field">
<label htmlFor="password"></label>
<input type="password" onChange={handleChange} />
</div>
<button className="btn pink z-depth-0 lighten-1 text-grey">Sign up</button>
</form>
)
}
我试图将其转换为功能组件,我在状态部分所能做的就是:
const [firstName, setFirstName] = useState('');
const [lastName, setLAstName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
然后为每个函数设置一个不同的函数来更改状态,而不是在类组件中handleChange
一个函数:
const handleFirstNameChange = (e) => {
setFirstName(e.target.value)
}
const handleFirstNameChange = (e) => {
setLastName(e.target.value)
}
const handleEmailChange= (e) => {
setEmail(e.target.value)
}
const handlePasswordChange= (e) => {
setPassword(e.target.value)
}
这很冗长,有没有办法使用钩子在经典组件中实现相同的东西?
在使用功能组件时,您不需要将状态拆分为多个状态,尤其是在以您的方式处理表单时,您可以执行以下操作:
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
const SignUp = () => {
const [state, setState] = React.useState({
firstName: '',
lastName: '',
email: '',
password: '',
})
const handleChange =(e) => {
e.persist();
setState(prevState => ({
...prevState,
[e.target.id]: e.target.value
}));
}
const handleSubmit = () => {
console.log(state);
}
return (
<form onSubmit={handleSubmit}>
<h5>Sign Up</h5>
<div className="input-field">
<label htmlFor="firstName">First Name</label>
<input type="text" id="firstName" onChange={handleChange}/>
</div>
<div className="input-field">
<label htmlFor="lastName">Last name</label>
<input type="text" id="lastName" onChange={handleChange}/ >
</div>
<div className="input-field">
<label htmlFor="email">Email</label>
<input type="email" id="email" onChange={handleChange} />
</div>
<div className="input-field">
<label htmlFor="password">Password</label>
<input type="password" id="password" onChange={handleChange} />
</div>
<button className="btn pink z-depth-0 lighten-1 text-grey">Sign up</button>
</form>
)
}
render(<SignUp />, document.getElementById('root'));
我只是为电子邮件和assword jsx节点添加了缺少的id,并将状态更改为使用useState,但保留了您之前在类组件中定义的形状。这样,您无需进行太多更改即可使其像以前一样工作。
在Stackblitz上看到这个复制
品只需将一个对象存储在您的React.usState
中:
const [formData, setFormData] = useState({
firstName: '',
lastName: '',
email: '',
password: '',
});
然后对handleChange
函数使用相同的逻辑:
function handleChange(e) {
setFormData({ ...formData, [e.target.id]: e.target.value })
}
你可以用一个useReducer来做到这一点:
import React, { useReducer } from "react";
const SignUp = () => {
function reducer(currentState, newState) {
return { ...currentState, ...newState };
}
const [{ firstName, lastName, email, password }, setState] = useReducer(
reducer,
{
firstName: "",
lastName: "",
email: "",
password: ""
}
);
const handleSubmit = event => {
event.preventDefault();
console.log("firstName: ", firstName);
console.log("lastName: ", lastName);
console.log("email: ", email);
console.log("password: ", password);
};
return (
<form onSubmit={handleSubmit}>
<h5>Sign Up</h5>
<div className="input-field">
<label htmlFor="firstName">First Name</label>
<input
type="text"
value={firstName}
id="firstName"
onChange={e => setState({ firstName: e.target.value })}
/>
</div>
<div className="input-field">
<label htmlFor="lastName">Last Name</label>
<input
type="text"
value={lastName}
id="lastName"
onChange={e => setState({ lastName: e.target.value })}
/>
</div>
<div className="input-field">
<label htmlFor="email">Email</label>
<input
type="email"
value={email}
onChange={e => setState({ email: e.target.value })}
/>
</div>
<div className="input-field">
<label htmlFor="password">Password</label>
<input
type="password"
value={password}
onChange={e => setState({ password: e.target.value })}
/>
</div>
<button className="btn pink z-depth-0 lighten-1 text-grey">
Sign up
</button>
</form>
);
};
export default SignUp;
https://codesandbox.io/s/serene-margulis-wz8ge