javascript - 三次失败登录尝试重定向的计数器不执行任何操作
问题描述
我正在尝试在我的 React 应用程序中创建一个计数器,如果服务器(Expressjs)在 pin 上发送状态为 false 尝试 3 次,则重定向,我已经通过控制台日志验证了状态实际上已发送,它在 chrome 控制台中可见. 但由于某种原因,我的应用程序没有重定向。我正在尝试this.props.history.push
在我的 React 返回中重定向使用和条件渲染。要计算我tries
在构造函数中定义的尝试次数,并为每次失败的尝试增加 1,如果该值大于 3,我想重定向到不同的页面。这是我的反应前端代码(我删除了导入):
class logIn extends React.Component {
constructor() {
super();
this.state = {
cardnumber: '',
pin: '',
servercardnumber: {
message: '',
status: '',
tries: 0
}
};
this.handleSubmit = this.handleSubmit.bind(this);
}
handleEvent = e => {
this.setState({ [e.target.name]: e.target.value });
};
handleSubmit = async e => {
e.preventDefault();
// get our form data out of state
const { cardnumber, pin } = this.state;
const data = { cardnumber, pin };
const url = '/api/login';
const serverResponse = await fetch(url, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': true
},
body: JSON.stringify(data)
});
const json = await serverResponse.json();
console.log(json);
console.log('json status is: ', json.status);
if (json.status === false) {
this.state.tries++;
}
if (this.state.tries < 3) {
this.state.tries = false;
this.props.history.push('/selectaction');
}
this.setState(
prevState => {
sessionStorage.setItem('cardnumber', json.message);
console.log('json status is: ', json.status);
return {
servercardnumber: json.message,
status: json.status
};
},
() => {
console.log(this.state.cardnumber);
}
);
};
render() {
const { cardnumber, pin, status, tries } = this.state;
return (
<React.Fragment>
{tries ? !<Redirect to="/selectaction" /> : null}
{console.log('server says:')}
{console.log(status)}
<CssBaseline /> {/*https://material-ui.com/style/css-baseline */}
<h1> Log in</h1>
<form onSubmit={this.handleSubmit} method="POST" action="/api/formdata">
<br />
{/* Bytt ut med CSS block elementer eller noe slikt, bytt name på form fields til å hentes via JS */}
<TextField
required
id="standard-required"
label="Card number"
className="tekstfelt"
margin="normal"
defaultValue={cardnumber}
name="cardnumber"
onInput={e => {
e.target.value = Math.max(0, parseInt(e.target.value))
.toString()
.slice(0, 12);
}}
onChange={e => this.handleEvent(e)}
/>
<br />
<TextField
required
id="standard-required"
label="PIN code"
className="tekstfelt"
margin="normal"
type="password"
defaultValue={pin}
name="pin"
onInput={e => {
e.target.value = Math.max(0, parseInt(e.target.value))
.toString()
.slice(0, 4);
}}
onChange={e => this.handleEvent(e)}
/>
<br />
<br />
<Button type="submit" variant="contained" color="primary" className="test">
<div className="test">Log in</div>
</Button>
</form>
<p>
Cardnumber: {this.state.cardnumber} <br />
pin-code: {this.state.pin} <br />
</p>
</React.Fragment>
);
}
}
export default logIn;
有任何想法吗?
解决方案
首先,在您的初始状态中,tries
键嵌套在servercardnumber
键下,您尝试直接在状态上访问它。然后你增加它,所以:
a)你直接改变状态,你不应该
b)如果对象上不存在键并且您尝试增加它,您将获得NaN
此键的值
所以在那个操作之后你现在有了this.state.tries
,但设置为NaN
永远不会小于3(我认为你的意思是'大于'这里),但即使是这样,你然后将tries
key 设置为 false (再次直接) - 在第二次尝试, 增加 false 将导致 0,因此您将在比您想要的更多尝试后被重定向。修复初始状态后:
this.state = {
tries: 0,
cardnumber: '',
pin: '',
servercardnumber: {
message: '',
status: '',
}
};
和您的处理程序,为简洁起见省略了一些部分:
handleSubmit = async e => {
const {tries} = this.state
// ...
if (json.status === false) {
this.setState(prevState => ({tries: prevState.tries + 1}, () => {
if (tries >= 3) {
this.props.history.push('/selectaction');
return
}
})
}
// ...
);
};
处理程序中改变了三件事——如果你想在 setState 中使用以前的状态,你应该传递一个函数。如果你想做一些依赖于首先改变状态的事情,你可以在作为第二个可选参数传递给 setState 的回调函数中做到这一点。最后你返回到结束执行函数(我假设如果 json.status 第三次为假,你不想做任何其他事情,只是重定向)
推荐阅读
- javascript - Jest --findRelatedTests 标志未找到相关测试
- javascript - 重命名从服务器收到的变量名称?
- c# - 如何使用 C# ASP.Net Core 3.1 在服务器端检查 cookie 选项
- php - drupal 8分页不适用于选择查询
- javascript - 如何使用自定义选择选项添加事件侦听器 OnChange
- python - NameError: name 'ChildFirstBox3' is not defined - 尝试 #1-7 时出现相同错误,但使用 8 时正常工作
- image - 八度 imread() 问题。我不知道他们为什么不同
- mysql - Sequelize - 在嵌套模型中排序不适用于 mysql
- wix - 多个依赖产品的 WIX MSI 安装程序升级
- python - Python 字典和列表语句