仅在从reducer更新收到我的道具后,我才想在表单上运行onSubmit。
const mapStateToProps = state => {
return {
authError: state.auth.authError // I want this to update before the action.
};
};
如果我在onSutmit处理程序中console.log authError,我会收到旧的authError。第二次运行它时,我收到更新的authError。
handleSubmit = e => {
e.preventDefault();
console.log("error exists?", this.props.authError);
this.props.signIn(this.state); //dispatches a login action
this.handleHideLogin(); // hides the form after action is dispatched
};
我只想在分派动作且错误为null后才隐藏表单。 (如果身份验证成功,它将自动返回null)
我尝试使用setTimeout()并在技术上可行,但是我想知道是否还有更“适当”的方法来实现它。
handleSubmit = e => {
e.preventDefault();
this.props.signIn(this.state);
setTimeout(() => {
if (this.props.authError) {
console.log("returns error =>", this.props.authError);
} else {
console.log("no error =>", this.props.authError);
this.handleHideLogin();
}
}, 500);
};
我组件的一部分供参考
<form onSubmit={!this.props.authError ? this.handleSubmit : null}>
//the above onSubmit is different if I use the setTimeout method.
<div className="modal-login-body">
<div className="modal-login-input">
<input
type="email/text"
name="email"
autoComplete="off"
onChange={this.handleChange}
required
/>
<label htmlFor="email" className="label-name">
<span className="content-name">EMAIL</span>
</label>
</div>
<div className="modal-login-input">
<input
type="password"
name="password"
autoComplete="off"
onChange={this.handleChange}
required
/>
<label htmlFor="password" className="label-name">
<span className="content-name">PASSWORD</span>
</label>
</div>
</div>
<div className="my-modal-footer">
<p className="login-failed-msg">
{this.props.authError ? this.props.authError : null}
</p>
<button type="submit" className="complete-login-button">
LOGIN
</button>
<a href="CHANGE" className="forgot-password">
<u>Forgot your password?</u>
</a>
</div>
</form>
答案 0 :(得分:1)
我假设this.props.signIn
是一个异步函数。
因此this.props.authError
是异步更新的,这就是为什么如果设置超时在某些情况下会起作用的原因(当您得到的响应时间少于5秒时)。
解决此问题的一种方法是使用then
和catch
而不更新表单状态
handleSubmit = e => {
e.preventDefault();
this.props.signIn(this.state).then(resp => {
this.setState({userIsValid: true, failure: null})
this.onUpdate(userIsValid);
})
.catch(err => {
this.setState({userIsValid: false, failure: "Failed to login"})
});
}
并使用if-else
确定是显示表单还是显示您的网站
class App extends React.Component {
render() {
if (this.state.isValidUser) {
return <Main />
} else {
return <LoginForm onUpdate={(isValid) => {this.setState({isValidUser: isValid})} />
}
}
}
换句话说,LoginForm组件存储用户名,密码,失败(登录失败的错误消息)和isValidUser(确定登录是否成功)。
该应用程序具有确定要显示的内容,网站或登录组件的状态。使用作为道具传递到登录组件的onUpdate
,我们可以更新App的状态并显示登录成功的网站。
希望对您有帮助。
答案 1 :(得分:0)
我通过在整个组件上进行条件渲染来解决了这个问题。 如果我登录,我使用了从react-router-dom重定向来仅不呈现该元素。
如果我已经登录,则无论如何都不需要显示登录表单。
if (this.props.loggedOut) {
<form onSubmit={this.handleSubmit}>
//...
</form>
} else {
return <Redirect to="/" />;
}