我正在尝试创建一个通用的表单组件来接受Login案例,Registration案例等。我在Login案例中大声笑,尽管usernameError
状态变为false,即用户走了,但我注意到了继续输入什么是实际的电子邮件,错误消息将持续存在:
我正在使用Indicative进行验证,但是问题出在我的组件上,我想是因为错误的状态正在实时更改,这就是问题所在。但是我不确定如何将useEffect
连接到我的onChange
处理程序。
这是我的组成部分:
import React, { useState, useEffect } from 'react';
import {
Loader,
Dimmer,
Transition,
Button,
Form,
Grid,
Header,
Message,
Segment
} from 'semantic-ui-react';
import axios from 'axios';
import {
logInUser,
userHasBeenVerified,
userHasNotBeenVerified,
resetCountNotVerified
} from '../../store/reducers/users/index';
import { Link } from 'react-router-dom';
import { validateInputs } from '../../utils/index';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
function FormComponent({
formType,
match,
isLoggedIn,
accountVerified,
userHasBeenVerified,
resetCountNotVerified
}) {
function isLoginForm() {
console.log('formType; ', formType);
return (
<div className="login-form">
{' '}
{}
<style>
{`body > div, body > div > div, body > div > div > div.login-form { height: 100%;}`}{' '}
</style>
<Grid textAlign="center" style={{ height: '100%' }} verticalAlign="middle">
<Grid.Column style={{ maxWidth: 450 }}>
<Header as="h2" color="green" textAlign="center">
Log-in to your account
</Header>
{console.log('usernameError ', usernameError)};
<Form
size="large"
onSubmit={e => handleSubmit(e, formType)}
error={formError}
>
<Segment stacked>
<Form.Input
fluid
icon="user"
iconPosition="left"
placeholder="E-mail address, e.g. joe@schmoe.com"
name="username"
value={username}
onChange={e => handleChange(e)}
error={usernameError}
/>
<Transition visible={usernameError} animation="scale" duration={duration}>
<Message error content={usernameFeedback} />
</Transition>
<Form.Input
fluid
icon="lock"
iconPosition="left"
placeholder="Password"
name="password"
type="password"
value={password}
onChange={e => handleChange(e)}
error={passwordError}
/>
<Transition visible={passwordError} animation="scale" duration={duration}>
<Message error content={passwordFeedback} />
</Transition>
<Button color="green" fluid size="large" disabled={disableButton}>
Log-in
</Button>
<br />
<Link to="/forgot_password">Forgot password?</Link>
<Transition
visible={accountVerified === false ? true : false}
unmountOnHide={true}
animation="scale"
duration={duration}
>
{isLoading ? (
<Dimmer active inverted>
<Loader />
</Dimmer>
) : (
<Message
color="yellow"
centered="true"
header={responseMessage[0]}
content={responseMessage[1]}
/>
)}
</Transition>
<Transition
visible={formError}
unmountOnHide={true}
animation="scale"
duration={duration}
>
{isLoading ? (
<Dimmer active inverted>
<Loader />
</Dimmer>
) : (
<Message
error
centered="true"
header={responseMessage[0]}
content={responseMessage[1]}
/>
)}
</Transition>
<Transition
visible={formSuccess}
unmountOnHide={true}
animation="scale"
duration={duration}
>
{isLoading ? (
<Dimmer active inverted>
<Loader />
</Dimmer>
) : (
<Message
success
header={responseMessage[0]}
content={responseMessage[1]}
/>
)}
</Transition>
</Segment>
</Form>
{formError ? (
<Transition visible={formError} animation="scale" duration={1000}>
{isLoading ? (
<Dimmer active inverted>
<Loader />
</Dimmer>
) : (
<Message>
<Link to="/register">Register</Link>{' '}
</Message>
)}
</Transition>
) : null}
</Grid.Column>{' '}
</Grid>{' '}
</div>
);
}
function loginSubmit() {
axios
.post('http://localhost:8016/users/login', {
username: username,
password: password
})
.then(response => {
console.log('response', response);
if (response.status === 200) {
userHasBeenVerified();
setTimeout(() => {
logInUser();
history.push('/profile');
}, 5000);
setUsername('');
setPassword('');
setFormError(false);
setFormSuccess(true);
setIsLoading(false);
setResponseMessage(response.data.msg);
}
})
.catch(function(error) {
if (error.response) {
if (error.response.status === 401) {
userHasNotBeenVerified();
setUsername('');
setPassword('');
setFormError(false);
setFormSuccess(true);
setIsLoading(false);
setResponseMessage(error.response.data.msg);
}
if (error.response.status === 404) {
resetCountNotVerified();
setUsername('');
setPassword('');
setFormError(true);
setFormSuccess(false);
setIsLoading(false);
setResponseMessage(error.response.data.msg);
}
console.log('error.response.data', error.response.data);
console.log('error.response.headers', error.response.headers);
}
});
}
var Forms = {
Login: [isLoginForm, loginSubmit],
}
var [fadeUp, setFadeUp] = useState('fade up');
var [duration, setDuration] = useState(500);
var [name, setName] = useState('');
var [username, setUsername] = useState('');
var [usernameFeedback, setUsernameFeedback] = useState('');
var [usernameError, setUsernameError] = useState(false);
var [userNameDup, setUserNameDup] = useState(false);
var [password, setPassword] = useState('');
var [passwordFeedback, setPasswordFeedback] = useState('');
var [passwordError, setPasswordError] = useState(false);
var [password_confirmation, setPasswordConfirmation] = useState('');
var [passwordConfirmationError, setPasswordConfirmationError] = useState(false);
var [passwordConfirmationFeedback, setPasswordConfirmationFeedback] = useState('');
var [formSuccess, setFormSuccess] = useState(false);
var [formError, setFormError] = useState(false);
var [disableButton, setDisableButton] = useState(true);
var [isLoading, setIsLoading] = useState(false);
var [responseMessage, setResponseMessage] = useState({});
var [tokenExpired, setTokenExpired] = useState(false);
var [responseCodeSuccess, setResponseCodeSuccess] = useState(false);
var [error, setError] = useState(false);
useEffect(() => { /* Not sure what to do here */
setUsernameError();
setPassword();
// }, []);
function handleChange(e) {
console.log('e ', e);
e.persist();
if (e.target.name === 'username') {
console.log('username', e.target.name);
setUsername(e.target.value);
}
if (e.target.name === 'password') {
console.log('password', e.target.name);
setPassword(e.target.value);
}
validateInputs(
formType,
username,
setUsernameError,
setUsernameFeedback,
password,
setPasswordError,
setPasswordFeedback,
setDisableButton
);
}
function handleSubmit(event, formType) {
event.preventDefault();
return Forms[formType][1]();
}
console.log('formType; ', formType);
return Forms[formType][0]();
}
function mapStateToProps(state) {
const { users } = state;
const { accountVerified, isLoggedIn } = users;
return { accountVerified, isLoggedIn };
}
const mapDispatchToProps = dispatch =>
bindActionCreators(
{ logInUser, userHasBeenVerified, userHasNotBeenVerified, resetCountNotVerified },
dispatch
);
export default connect(
mapStateToProps,
mapDispatchToProps
)(FormComponent);
因此,总结一下,我认为useEffect
应该如何监听userNameError
和passwordError
的错误状态的更改,因为我认为这是问题所在。
更新:
这是我认为Iarz的意思的演示。
useEffect(() => {
if (usernameError) {
return usernameError;
}
if (passwordError) {
return passwordError;
}
}, [usernameError, passwordError]);
答案 0 :(得分:1)
useEffect
的第二个参数是一系列要观察的东西,因此它知道何时触发。对于当前的空数组,它仅在安装时触发(如果包含返回,则将在unMount上触发)。你什么时候要开火?尝试将其更改为[passwordError, userNameError]
。
答案 1 :(得分:1)
尽管您可以通过使用useEffect
中的依赖项数组来跟踪输入的变化,但是即使输入是原始的或键入的值是有效的,也会出现错误ui(红色背景)的问题。
为什么不验证表单onSubmit
并在这里避免使用useEffect
? Imo是使用语义UI React验证表单的更好方法。