寻找正确方向的轻推。处理React项目并使用钩子。是的,已经阅读了文档,但是还没有完全理解。
询问与登录例程有关。登录表单有效,但是直到重复提交后,它才反映失败的登录状态;所以我得到的是以前的状态,而不是当前的状态。
尝试useEffect ...不变。代码紧随其后,并感谢任何建设性的反馈意见:
从“登录”表单
let devicesInfo = [
{ '96abc32b47fc10c88704b9a799c65b5c05455f4a9ef92013': '::1' },
{ '96abc32b47fc10c88704b9a799c65b5c05455f4a9ef92013': '::1' },
{ '96abc32b47fc10c88704b9a799c65b5c05455f4a9ef92013': '::1' }
]
let deviceId= "96abc32b47fc10c88704b9a799c65b5c05455f4a9ef92013"
从身份验证切片中:
import React, { useState, useEffect, useRef } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { Redirect } from 'react-router-dom'
import getAuthStatus from 'common/cyclone/auth/authenticated.status'
import {
authenticateByLogin,
authenticationSelector,
} from '../services/auth.service'
import Form from 'react-validation/build/form'
import Input from 'react-validation/build/input'
import CheckButton from 'react-validation/build/button'
const required = (value) => {
if (!value) {
return (
<div className="alert alert-danger" role="alert">
This field is required!
</div>
)
}
}
const Login = (props) => {
const form = useRef()
const checkBtn = useRef()
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [loading, setLoading] = useState(false)
const [errorMessage, setErrorMessage] = useState(null)
const dispatch = useDispatch()
const { session, hasErrors } = useSelector(authenticationSelector)
useEffect(() => {}, [session, hasErrors])
const onChangeUsername = (e) => {
const username = e.target.value
setUsername(username)
}
const onChangePassword = (e) => {
const password = e.target.value
setPassword(password)
}
const handleLogin = (e) => {
e.preventDefault()
setLoading(true)
form.current.validateAll()
if (checkBtn.current.context._errors.length === 0) {
dispatch(authenticateByLogin(username, password))
.then(() => {
setLoading(false)
if (hasErrors) {
setErrorMessage(session.error.message)
} else {
//props.history.push('/profile')
// window.location.reload()
}
})
.catch(() => {
setLoading(false)
})
} else {
setLoading(false)
}
}
if (session.success) {
//console.log(session.success)
return <Redirect to="/profile" />
}
if (getAuthStatus()) {
return <Redirect to="/profile" />
}
return (
<div className="col-md-12">
<div className="card card-container">
<img
src="//ssl.gstatic.com/accounts/ui/avatar_2x.png"
alt="profile-img"
className="profile-img-card"
/>
<Form onSubmit={handleLogin} ref={form}>
<div className="form-group">
<label htmlFor="username">Username</label>
<Input
type="text"
className="form-control"
name="username"
value={username}
onChange={onChangeUsername}
validations={[required]}
/>
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<Input
type="password"
className="form-control"
name="password"
value={password}
onChange={onChangePassword}
validations={[required]}
/>
</div>
<div className="form-group">
<button className="btn btn-primary btn-block" disabled={loading}>
{loading && (
<span className="spinner-border spinner-border-sm"></span>
)}
<span>Login</span>
</button>
</div>
{hasErrors && (
<div className="form-group">
<div className="alert alert-danger" role="alert">
{errorMessage}
</div>
</div>
)}
<CheckButton style={{ display: 'none' }} ref={checkBtn} />
</Form>
</div>
</div>
)
}
export default Login
答案 0 :(得分:1)
尝试更改hasError更改时的消息
useEffect(()=> {
if(hasErrors) {
setErrorMessage(session.error.message)
}
}, [hasErrors]);
答案 1 :(得分:0)
这是一些代码,因此我只是跳过以解决问题,而不是将所有内容分开。我最好的猜测是这部分:
dispatch(authenticateByLogin(username, password))
.then(() => {
setLoading(false)
if (hasErrors) {
setErrorMessage(session.error.message)
} else {
//props.history.push('/profile')
// window.location.reload()
}
})
.catch(() => {
setLoading(false)
})
在这里执行异步身份验证,然后根据“ hasError”执行操作。此“ hasError”来自一个钩子。我们(或至少我)不知道如何进行管理。问题是,您无法100%确保在then代码块中检查hasError确实值得信赖。该挂钩可能会在下一个渲染之后运行,这说明了为什么看到了上一个状态,而不是实际的状态。
最好的猜测是使用异步调用的响应,因为应该有一个=> authenticate.then((response)=> if(response.hasError)...) 通过此检查,您可以设置自己的错误状态,并且组件应该是最新的
让我知道这是否可以解决您的错误。