javascript - 三次登录尝试失败时重定向的计数器不会执行任何操作

标签 javascript reactjs

我正在尝试在我的 React 应用程序中创建一个计数器,如果服务器(Expressjs)在 pin 尝试上发送状态 false 3 次,则该计数器会重定向,我已经通过控制台日志验证了状态实际上已发送,它在 Chrome 控制台。但由于某种原因,我的应用程序没有重定向。我正在尝试使用 this.props.history.push 和 React 返回中的条件渲染来重定向。为了计算尝试次数,我在构造函数中定义了 tries ,并为每次失败的尝试将该值增加 1,如果该值大于 3,我想重定向到其他页面。这是我的 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;

有什么想法吗?

最佳答案

首先,在初始状态下,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 的回调函数中执行此操作。最后你返回到结束执行函数(我假设如果 json.status 第三次为 false,你不想做任何其他事情而只是重定向)

关于javascript - 三次登录尝试失败时重定向的计数器不会执行任何操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53192119/

相关文章:

javascript - 如果未启用 JavaScript,则卡住带有覆盖的屏幕

javascript - 使用父 onclick 事件显示和隐藏隐藏的 div

javascript - AWS Transcribe:不支持的音频格式:matroska,webm

JavaScript 和 CSS Accordion 列表

javascript - 悬停时的 React-jss 转换

javascript - Flash 对象未正确嵌入 IE 中

javascript - 为什么当我使用 .map 而不是硬编码来动态填充内容时,Material UI 选项卡停止工作?

javascript - 路径无效时重定向到错误页面

javascript - LocalStorage 项目被新项目覆盖

reactjs - 未从 stylelint/stylelint-config-styled-components 获取结果或错误