ReactJs: предотвращение многократного нажатия кнопки

в моем компоненте React у меня есть кнопка, предназначенная для отправки некоторых данных через AJAX при нажатии. Мне нужно произойти только в первый раз, т. е. отключить кнопку после ее первого использования.

Как я пытаюсь сделать это:

var UploadArea = React.createClass({

  getInitialState() {
    return {
      showUploadButton: true
    };
  },

  disableUploadButton(callback) {
    this.setState({ showUploadButton: false }, callback);
  },

  // This was simpler before I started trying everything I could think of
  onClickUploadFile() {
    if (!this.state.showUploadButton) {
      return;
    }
    this.disableUploadButton(function() {
      $.ajax({
        [...]
      });

    });
  },

  render() {
    var uploadButton;
    if (this.state.showUploadButton) {
      uploadButton = (
        <button onClick={this.onClickUploadFile}>Send</button>
      );
    }

    return (
      <div>
        {uploadButton}
      </div>
    );
  }

});

Я думаю, что происходит переменная состояния showUploadButton не обновляется сразу, что, как говорят документы React, ожидается.

Как я могу заставить кнопку отключиться или уйти все вместе в тот момент, когда она щелкнул?

3 ответов


что вы можете сделать, это отключить кнопку после нажатия и оставить ее на странице (не кликабельный элемент).

для этого вам нужно добавить ссылку на элемент button

<button ref="btn" onClick={this.onClickUploadFile}>Send</button>

а затем на функции onClickUploadFile отключите кнопку

this.refs.btn.setAttribute("disabled", "disabled");

затем вы можете настроить отключенную кнопку соответственно, чтобы дать некоторую обратную связь пользователю с

.btn:disabled{ /* styles go here */}

при необходимости убедитесь, что его можно восстановить с

this.refs.btn.removeAttribute("disabled");

обновление: предпочтительным способом обработки ссылок в React является функция, а не строка.

<button 
  ref={btn => { this.btn = btn; }} 
  onClick={this.onClickUploadFile}
>Send</button>


this.btn.setAttribute("disabled", "disabled");
this.btn.removeAttribute("disabled");

вот небольшой пример использования кода, который вы предоставили https://jsfiddle.net/69z2wepo/30824/


испытано как работая одно:http://codepen.io/zvona/pen/KVbVPQ

class UploadArea extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      isButtonDisabled: false
    }
  }

  uploadFile() {
    // first set the isButtonDisabled to true
    this.setState({
      isButtonDisabled: true
    });
    // then do your thing
  }

  render() {
    return (
      <button
        type='submit'
        onClick={() => this.uploadFile()}
        disabled={this.state.isButtonDisabled}>
        Upload
      </button>
    )
  }
}

ReactDOM.render(<UploadArea />, document.body);

решение состоит в том, чтобы проверить состояние сразу после входа в обработчик. React гарантирует, что setState внутри интерактивных событий (например, click) сбрасывается на границе событий браузера. Ref:https://github.com/facebook/react/issues/11171#issuecomment-357945371

// In constructor
this.state = {
    disabled : false
};


// Handler for on click
handleClick = (event) => {
    if (this.state.disabled) {
        return;
    }
    this.setState({disabled: true});
    // Send     
}

// In render
<button onClick={this.handleClick} disabled={this.state.disabled} ...>
    {this.state.disabled ? 'Sending...' : 'Send'}
<button>