React Class组件转Hooks:登录记住密码功能失效求助
React Hooks版本「记住我」功能失效问题排查
问题描述
需要实现登录时的「记住我」功能,从CodeSandbox获取了React Class组件版本的实现代码,转换为React Hooks版本后功能无法正常运行,请求排查代码问题。
原React Class组件代码
import React from "react"; class RememberMe extends React.Component { static displayName = "RememberMe"; state = { email: "", password: "", isChecked: false }; componentDidMount() { if (localStorage.checkbox && localStorage.username !== "") { this.setState({ isChecked: true, email: localStorage.username, password: localStorage.password }); } } onChangeValue = (event) => { this.setState({ [event.target.name]: event.target.value }); }; onChangeCheckbox = (event) => { this.setState({ isChecked: event.target.checked }); }; loginSubmit = () => { const { email, password, isChecked } = this.state; if (isChecked && email !== "") { localStorage.username = email; localStorage.password = password; localStorage.checkbox = isChecked; } }; render() { const { email, password, isChecked } = this.state; return ( <div> <form> <table align="center"> <tr> <td> <label>Email</label> </td> <td> <input type="email" name="email" value={email} onChange={this.onChangeValue} /> </td> </tr> <tr> <td> <label>Password</label> </td> <td> <input type="password" name="password" value={password} onChange={this.onChangeValue} /> </td> </tr> <tr> <td colSpan="2"> <input type="checkbox" checked={isChecked} name="lsRememberMe" onChange={this.onChangeCheckbox} /> <label>Remember me</label> </td> </tr> <tr> <td colSpan="2"> <input type="button" value="Login" onClick={this.loginSubmit} /> </td> </tr> </table> </form> </div> ); } } export default RememberMe;
自行编写的React Hooks版本代码
import React, { useState, useEffect } from "react"; const Me = () => { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [isChecked, setIsChecked] = useState(false); useEffect(() => { if (localStorage.checkbox && localStorage.email !== "") { setEmail({ email: localStorage.username }); setPassword({ password: localStorage.password }); setIsChecked({ isChecked: true }); } }, []); const onChangeValue = (event) => { setIsChecked({ [event.target.name]: event.target.value }); }; const onChangeCheckbox = (event) => { setIsChecked({ isChecked: event.target.checked }); }; const loginSubmit = () => { if (isChecked && email !== "") { localStorage.username = email; localStorage.password = password; localStorage.checkbox = isChecked; } }; return ( <div> <form> <table align="center"> <tr> <td> <label>Email</label> </td> <td> <input type="email" name="email" value={email} onChange={onChangeValue} /> </td> </tr> <tr> <td> <label>Password</label> </td> <td> <input type="password" name="password" value={password} onChange={onChangeValue} /> </td> </tr> <tr> <td colSpan="2"> <input type="checkbox" checked={isChecked} name="lsRememberMe" onChange={onChangeCheckbox} /> <label>Remember me</label> </td> </tr> <tr> <td colSpan="2"> <input type="button" value="Login" onClick={loginSubmit} /> </td> </tr> </table> </form> </div> ); }; export default Me;
问题排查与修正
你的Hooks版本代码存在以下几个关键错误:
1. 状态更新方式错误
useState返回的setter函数需要直接传入状态值,而非对象。你在useEffect、onChangeValue、onChangeCheckbox中错误地传入了对象,导致状态类型混乱:
- 正确写法:
setEmail(localStorage.username)而非setEmail({ email: localStorage.username }) - 正确写法:
setIsChecked(event.target.checked)而非setIsChecked({ isChecked: event.target.checked })
2. onChangeValue函数绑定错误
该函数应该根据输入框的name属性更新对应的email或password状态,但你错误地调用了setIsChecked,导致输入框内容无法正常更新。
3. localStorage读取判断条件错误
原Class组件中判断的是localStorage.username !== "",而你写成了localStorage.email !== "",导致组件挂载时无法正确读取存储的账号信息。
修正后的Hooks代码
import React, { useState, useEffect } from "react"; const Me = () => { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [isChecked, setIsChecked] = useState(false); useEffect(() => { // 修正判断条件,匹配原Class逻辑 if (localStorage.checkbox && localStorage.username !== "") { setEmail(localStorage.username); setPassword(localStorage.password); setIsChecked(true); } }, []); const onChangeValue = (event) => { const { name, value } = event.target; // 根据name更新对应状态 if (name === "email") { setEmail(value); } else if (name === "password") { setPassword(value); } }; const onChangeCheckbox = (event) => { // 直接传入布尔值更新状态 setIsChecked(event.target.checked); }; const loginSubmit = () => { if (isChecked && email !== "") { localStorage.username = email; localStorage.password = password; localStorage.checkbox = isChecked; } }; return ( <div> <form> <table align="center"> <tr> <td> <label>Email</label> </td> <td> <input type="email" name="email" value={email} onChange={onChangeValue} /> </td> </tr> <tr> <td> <label>Password</label> </td> <td> <input type="password" name="password" value={password} onChange={onChangeValue} /> </td> </tr> <tr> <td colSpan="2"> <input type="checkbox" checked={isChecked} name="lsRememberMe" onChange={onChangeCheckbox} /> <label>Remember me</label> </td> </tr> <tr> <td colSpan="2"> <input type="button" value="Login" onClick={loginSubmit} /> </td> </tr> </table> </form> </div> ); }; export default Me;
内容的提问来源于stack exchange,提问作者Kia Kalista
相关产品推荐
相关产品推荐

