简体   繁体   English

在三个失败的登录尝试上重定向的计数器没有任何作用

[英]Counter to redirect on three failed login attempts does nothing

I'm trying to make a counter in my React app that redirects if the server (Expressjs) sends status false on a pin try 3 times, I've verified through console logs that the status is actually sent, it's visibible in the chrome console. 我正在尝试在我的React应用程序中创建一个计数器,如果服务器(Expressjs)在引脚尝试发送3次状态为false时将重定向,我已经通过控制台日志验证了状态实际上是已发送,在chrome控制台中可见。 But for some reason my app does not redirect. 但是由于某种原因,我的应用程序无法重定向。 I'm trying to redirect both using this.props.history.push and a conditional render in my React return. 我正在尝试在我的React返回中使用this.props.history.push和条件渲染进行重定向。 To count number of tries I have defined tries in my constructor and increase this value by 1 for every failed attempt, if the value is greater than 3 I want to redirect to a different page. 要计算已在构造函数中定义的tries次数,并为每次失败的尝试将此值增加1,如果该值大于3,我想重定向到另一个页面。 Here is my react front end code (I removed the imports): 这是我的反应前端代码(我删除了导入):

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;

Any ideas? 有任何想法吗?

first of all, in your initial state tries key is nested under servercardnumber key and you're trying to access it on state directly. 首先,在初始状态下tries关键是嵌套在servercardnumber键,你要直接访问它的状态。 then you increment it, so: 然后增加它,所以:

a) you mutate state directly, which you shouldn't a)您直接更改状态,这是不应该的

b) if key does not exist on object and you try to increment it, you will get NaN as value of this key b)如果键不存在于对象上并且您尝试增加它,则将获得NaN作为此键的值

so after that operation you now have this.state.tries , but set to NaN which will never be smaller than 3 (i think you meant 'greater than' here), but even if it was, you then set tries key to false (again directly) - on second try, incrementing false would result in 0, so you would get redirected after more attempts than you want. 使手术后你现在有this.state.tries ,但设置为NaN ,它们不会小于3(我想你的意思“大于”在这里),但即使是,你再设置tries键为false(再次直接)-在第二次尝试中,增加false将导致0,因此,如果尝试次数超过您的期望,您将被重定向。 After fixing the initial state: 固定初始状态后:

  this.state = {
    tries: 0,
    cardnumber: '',
    pin: '',
    servercardnumber: {
      message: '',
      status: '',
    }
  };

and your handler, some parts omitted for brevity: 和您的处理程序,为简洁起见,省略了一些部分:

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
        }
      })
    }
    // ...
    );
  };

three things changed in handler - if you want to use previous state in setState, you should pass a function. 处理程序中发生了三件事-如果要在setState中使用以前的状态,则应传递一个函数。 if you want to do something that relies on state being changed first, you can do that in callback function passed to setState as second, optional argument. 如果要执行依赖于状态首先更改的操作,则可以在作为第二个可选参数传递给setState的回调函数中执行此操作。 and at the end you return to end executing function (i assume that if json.status is false for the third time you don't want to do anything else and just redirect) 然后最后返回执行函数(我假设如果json.status第三次为false,则您不想执行任何其他操作而只是重定向)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM