我试着在我的React应用程序中做一个计数器,如果服务器(Expressjs)三次在引脚上发送状态为false,我已经通过控制台日志验证了状态是实际发送的,在铬控制台中是可见的。但出于某种原因,我的应用程序不会重定向。我正在尝试使用this.props.history.push和redirect中的条件呈现来重定向。要计数尝试次数,我在构造函数中定义了tries,如果该值大于3,我希望重定向到另一个页面,则每次尝试失败时,将该值增加1。下面是我的react前端代码(我删除了导入):
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;有什么想法吗?
发布于 2018-11-07 15:34:56
首先,在初始状态中,tries键嵌套在servercardnumber密钥下,并且您试图在状态下直接访问它。然后增加它,所以:
( a)你直接变异状态,你不应该这样做
( b)如果对象上不存在密钥,并且尝试增加它,则将得到NaN作为该键的值。
因此,在该操作之后,您现在有了this.state.tries,但是将其设置为NaN,它永远不会小于3(我认为您的意思是“大于”),但即使是这样,您也可以将tries键设置为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的回调函数中这样做,作为第二个可选参数。在结束时,返回到end执行函数(如果json.status第三次是假的,那么您就不想做任何其他事情,而只是重定向)。
https://stackoverflow.com/questions/53192119
复制相似问题