重用 AuthForm 组件而不在状态中发送不必要的信息
Reusing an AuthForm component without sending unnecessary info in state
我在 /signup 和 /login 页面上都使用了一个 AuthForm 组件,我使用 formType 属性来区分这两者。注册页面需要一些额外的字段,包括性别和出生日期(可能是将来的地址),而登录表单可以相当简单。
从显示的角度来看,这很简单,因为我可以根据 formType 属性的值显示或隐藏那些额外的字段。它变得复杂的地方是状态。
我考虑过两种不同的状态管理方法:1) 使用 useFormInput() 挂钩,以及 2) 使用 useState 挂钩结合状态对象(模仿有状态组件方法)。
选项 1:
const useFormInput = (initialValue) => {
const [value, setValue] = useState(initialValue);
function handleChange(e) {
setValue(e.target.value);
}
return {
value,
onChange: handleChange
};
}
const AuthForm = ({ buttonText, formType, onAuth }) => {
const email = useFormInput('');
const password = useFormInput('');
...
const handleSubmit = (e) => {
e.preventDefault();
onAuth(formType, {email, password, etc);
return (
<form onSubmit={handleSubmit}>
<label htmlFor="email">E-mail</label>
<input
id="email"
name="email"
type="text"
{...email}
/>
...
)
};
}
选项 2
const AuthForm = ({ buttonText, formType, onAuth }) => {
const [state , setState] = useState({
email : "",
password : "",
firstName: "",
lastName: "",
gender: "",
dob: ""
})
const handleChange = e => {
const {name , value} = e.target;
setState( prevState => ({
...prevState,
[name] : value
}))
}
const handleSubmit = (e) => {
e.preventDefault();
console.log(state);
onAuth(formType, state);
return (
<form onSubmit={handleSubmit}>
<label htmlFor="email">E-mail</label>
<input
id="email"
name="email"
onChange={handleChange}
type="text"
value={state.email}
/>
...
)
};
}
无论采用哪种方法,我似乎都无法避免必须声明每个状态变量。当我在选项 2 中设置 state = {} 时,我收到有关将不受控组件更改为受控组件的错误。当我声明我所有的状态变量时,这意味着我的登录表单将在状态中包含 gender="",这将覆盖我数据库中的值。
我怎样才能 A) 避免完全声明状态变量,或者 B) 使我的最终状态只包含适合 AuthForm 使用上下文的字段?
您可以尝试根据 formType 创建初始状态(选项 2)。
const AuthForm = ({ buttonText, formType, onAuth }) => {
initialStateLogin = {
email : "",
password : "",
};
initialStateSignup = {
email : "",
password : "",
firstName: "",
lastName: "",
gender: "",
dob: ""
};
const [state , setState] = useState(formType === 'login' ? initialStateLogin : initialStateSignup);
//rest of the code..
}
我在 /signup 和 /login 页面上都使用了一个 AuthForm 组件,我使用 formType 属性来区分这两者。注册页面需要一些额外的字段,包括性别和出生日期(可能是将来的地址),而登录表单可以相当简单。
从显示的角度来看,这很简单,因为我可以根据 formType 属性的值显示或隐藏那些额外的字段。它变得复杂的地方是状态。
我考虑过两种不同的状态管理方法:1) 使用 useFormInput() 挂钩,以及 2) 使用 useState 挂钩结合状态对象(模仿有状态组件方法)。
选项 1:
const useFormInput = (initialValue) => {
const [value, setValue] = useState(initialValue);
function handleChange(e) {
setValue(e.target.value);
}
return {
value,
onChange: handleChange
};
}
const AuthForm = ({ buttonText, formType, onAuth }) => {
const email = useFormInput('');
const password = useFormInput('');
...
const handleSubmit = (e) => {
e.preventDefault();
onAuth(formType, {email, password, etc);
return (
<form onSubmit={handleSubmit}>
<label htmlFor="email">E-mail</label>
<input
id="email"
name="email"
type="text"
{...email}
/>
...
)
};
}
选项 2
const AuthForm = ({ buttonText, formType, onAuth }) => {
const [state , setState] = useState({
email : "",
password : "",
firstName: "",
lastName: "",
gender: "",
dob: ""
})
const handleChange = e => {
const {name , value} = e.target;
setState( prevState => ({
...prevState,
[name] : value
}))
}
const handleSubmit = (e) => {
e.preventDefault();
console.log(state);
onAuth(formType, state);
return (
<form onSubmit={handleSubmit}>
<label htmlFor="email">E-mail</label>
<input
id="email"
name="email"
onChange={handleChange}
type="text"
value={state.email}
/>
...
)
};
}
无论采用哪种方法,我似乎都无法避免必须声明每个状态变量。当我在选项 2 中设置 state = {} 时,我收到有关将不受控组件更改为受控组件的错误。当我声明我所有的状态变量时,这意味着我的登录表单将在状态中包含 gender="",这将覆盖我数据库中的值。
我怎样才能 A) 避免完全声明状态变量,或者 B) 使我的最终状态只包含适合 AuthForm 使用上下文的字段?
您可以尝试根据 formType 创建初始状态(选项 2)。
const AuthForm = ({ buttonText, formType, onAuth }) => {
initialStateLogin = {
email : "",
password : "",
};
initialStateSignup = {
email : "",
password : "",
firstName: "",
lastName: "",
gender: "",
dob: ""
};
const [state , setState] = useState(formType === 'login' ? initialStateLogin : initialStateSignup);
//rest of the code..
}