假设,要做一个登录系统,需要输入账号和密码,账号和密码由一个对象
userInfo
进行管理,我们可以初始化一个对象
let [userInfo, setUserInfo] = useState({
account: "",
password: ""
})
输入框可以采用受控方式:
<div className="inputItem">
<span>账号: </span>
<Input
placeholder="请输入邮箱"
value={userInfo.account}
onChange={(e) => handleInput(e, "account")}
type="text"
></Input>
</div>
<div className="inputItem">
<span>密码: </span>
<Input
placeholder="请牢记您的密码"
value={userInfo.password}
onChange={(e) => handleInput(e, "password")}
type="password"
></Input>
</div>
如果你的
onChange
的处理函数是这样写的:
const handleInput = (e, type) => {
if (type === "account") {
setUserInfo(pre => {
pre.account = e.target.value
return pre
})
} else {
setUserInfo(pre => {
pre.password= e.target.value
return pre
})
}
};
你会发现一个问题:虽然
pre
确实是被修改了,也确实是被返回了,但是不管输入什么
input
都是没有值的(
userInfo
实际上没有被修改)。
这个问题的关键其实我们都知道:
state不能通过直接赋值的方式修改,这也是我们为什么要解构出setUserInfo的原因
到这里你可能很疑惑,我是用的
setUserInfo
呀?
但是看上面传入
setUserInfo
中的函数,传入函数是为了解决需要用到之前的state值的需求,这个
pre
就是之前的 state,可是在这个函数中,却直接使用了
pre.account = e.target.value
这样的形式,
用 = 给一个 state 赋值了!
既要获取之前的state值,又不能在原先的state对象上面直接修改,所以我们使用
深拷贝
这个方法,生成一个临时对象,在这个上面修改,然后通过
setUserInfo
更改state:
const handleInput = (e, type) => {
let temp = JSON.parse(JSON.stringify(userInfo)); // 深拷贝对象
if (type === "account") {
temp.account = e.target.value;
} else {
temp.password = e.target.value;
}
setUserInfo(temp);
};