React 中的 onChange 输入延迟
onChange input delay in React
我以前从来没有真正注意到这一点;不确定我的代码中是否存在错误或者 onChange 是否始终以这种方式运行,但我遇到了输入延迟并且不确定如何解决它。这是我的意思的一个例子:
如您所见,控制台只打印之前的状态,这很麻烦,因为这意味着要让用户登录,他们必须单击“开始”按钮两次才能接收到正确的状态,即使用户名和密码已正确输入。
我的代码相当简单:
const [state, setState] = useState<LoginStateType>(iLoginState)
const {username, password} = state
const handleChange = (event: ChangeEventType) => {
const {name, value} = event.target
setState({...state, [name]: value})
console.log(username)
}
{...}
<input type="text" name="username" value={username} onChange={handleChange}/>
<input type="text" name="password" value={password} onChange={handleChange}/>
感谢任何帮助,谢谢!
自 State Updates May Be Asynchronous.
有了钩子,这可以通过
来实现
const [state, setState] = useState(/* ... */)
setState(/* ... */)
useEffect(() => {
// state is guaranteed to be what you want
}, [state])
setState 是一个异步步骤,不会立即获取新值!
我最后做的可能有点麻烦,但它完成了工作。除了状态(这是我设置的 useContext 所必需的)之外,我还设置了两个 useRef 常量:
const inputUserName = useRef<HTMLInputElement | null>(null)
const inputPassword = useRef<HTMLInputElement | null>(null)
{...}
<input type="text" name="username" ref={inputUserName} value={username} onChange={handleChange}/>
<input type={inputType as string} ref={inputPassword} name="password" value={password} onChange={handleChange}/>
所以我的完整代码如下:
//-------------ADMIN STATE-------------
const [state, setState] = useState<LoginStateType>(iLoginState)
const {username, password} = state
//-------------USE EFFECT-------------
//UseEffect: this is called when the context is set, I think
useEffect(() => {
//dispatch must be called before submit, I think because its an asynchronous call
dispatch(getAdminsRedux());
setContext(localStorage.getItem('user'))
if (context !== null){
navigate("/admin", {replace: true})
}
}, [setContext, context, dispatch, navigate]);
//-------------HANDLE CHANGE-------------
const handleChange = (event: ChangeEventType) => {
const {name, value} = event.target
setState({...state, [name]: value})
}
//-------------HANDLE LOGIN-------------
const handleLogin = async (event: MouseEvent) => {
event.preventDefault()
admins.forEach(async (admin) => {
if(admin.username === inputUserName.current!.value){
const comparedHash = compareHash(inputPassword.current!.value, admin.password)
if (comparedHash){
setContext(state.username)
localStorage.setItem('user', state.username)
}
}
});
}
我以前从来没有真正注意到这一点;不确定我的代码中是否存在错误或者 onChange 是否始终以这种方式运行,但我遇到了输入延迟并且不确定如何解决它。这是我的意思的一个例子:
如您所见,控制台只打印之前的状态,这很麻烦,因为这意味着要让用户登录,他们必须单击“开始”按钮两次才能接收到正确的状态,即使用户名和密码已正确输入。
我的代码相当简单:
const [state, setState] = useState<LoginStateType>(iLoginState)
const {username, password} = state
const handleChange = (event: ChangeEventType) => {
const {name, value} = event.target
setState({...state, [name]: value})
console.log(username)
}
{...}
<input type="text" name="username" value={username} onChange={handleChange}/>
<input type="text" name="password" value={password} onChange={handleChange}/>
感谢任何帮助,谢谢!
自 State Updates May Be Asynchronous.
有了钩子,这可以通过
来实现const [state, setState] = useState(/* ... */)
setState(/* ... */)
useEffect(() => {
// state is guaranteed to be what you want
}, [state])
setState 是一个异步步骤,不会立即获取新值!
我最后做的可能有点麻烦,但它完成了工作。除了状态(这是我设置的 useContext 所必需的)之外,我还设置了两个 useRef 常量:
const inputUserName = useRef<HTMLInputElement | null>(null)
const inputPassword = useRef<HTMLInputElement | null>(null)
{...}
<input type="text" name="username" ref={inputUserName} value={username} onChange={handleChange}/>
<input type={inputType as string} ref={inputPassword} name="password" value={password} onChange={handleChange}/>
所以我的完整代码如下:
//-------------ADMIN STATE-------------
const [state, setState] = useState<LoginStateType>(iLoginState)
const {username, password} = state
//-------------USE EFFECT-------------
//UseEffect: this is called when the context is set, I think
useEffect(() => {
//dispatch must be called before submit, I think because its an asynchronous call
dispatch(getAdminsRedux());
setContext(localStorage.getItem('user'))
if (context !== null){
navigate("/admin", {replace: true})
}
}, [setContext, context, dispatch, navigate]);
//-------------HANDLE CHANGE-------------
const handleChange = (event: ChangeEventType) => {
const {name, value} = event.target
setState({...state, [name]: value})
}
//-------------HANDLE LOGIN-------------
const handleLogin = async (event: MouseEvent) => {
event.preventDefault()
admins.forEach(async (admin) => {
if(admin.username === inputUserName.current!.value){
const comparedHash = compareHash(inputPassword.current!.value, admin.password)
if (comparedHash){
setContext(state.username)
localStorage.setItem('user', state.username)
}
}
});
}