假设,要做一个登录系统,需要输入账号和密码,账号和密码由一个对象userInfo
进行管理,我们可以初始化一个对象
let [userInfo, setUserInfo] = useState({account: "",password: ""
})
输入框可以采用受控方式:
<div className="inputItem"><span>账号: </span><Inputplaceholder="请输入邮箱"value={userInfo.account}onChange={(e) => handleInput(e, "account")}type="text"></Input>
</div>
<div className="inputItem"><span>密码: </span><Inputplaceholder="请牢记您的密码"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.valuereturn pre})} else {setUserInfo(pre => {pre.password= e.target.valuereturn 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);};