React-在ajax调用期间未禁用按钮,toast无法正常工作

时间:2019-02-22 21:33:53

标签: javascript ajax reactjs

页面上我只有几个按钮,如果我单击按钮,就会进行ajax调用。我想禁用该按钮,以使用户不会再次单击它,并且不会进行另一个Ajax调用。

我尝试了以下代码,但该按钮未禁用。 我也想显示成功响应的通知-我尝试了吐司,但是也没有用。

还有其他方法可以在反应中显示气球弹出吗?

请提出建议,

    onClickRun(params) {

    const url = `/api/${params}/run`;
    const id = "run"+params;
    return $.ajax({
        type: 'POST',
        url,
        processData: false,
        contentType: 'application/json',
        beforeSend :() =>{
           // $("#run"+params).classList.add("cursorDisabled");
           // $("#run"+params).attr('disabled',true);   
            document.getElementById(id).disabled = true;
            document.getElementById(id).classList.add('cursorDisabled');             
        },
        success: (response) => { 
            if(!response.error) {

                // toast({
                //     message: 'Pipeline ran successfully.',
                //     flavor: 'success',
                //     options: { timeOut: 5000 }
                // });
                //$("#"+params).classList.remove("cursorDisabled");
                //$("#run"+params).attr('disabled',false);
                document.getElementById(id).disabled = false;
                  document.getElementById(id).classList.remove('cursorDisabled'); 
                location.reload(true);
            }
        },
        error: (error) => {
            console.log("error");
        }
    });
}

CSS代码:

.cursorDisabled{
    cursor: not-allowed;
    color: gray;
}

按钮:

<button id= {"run"+col.name} type="button" onClick={() =>  this.onClickRun(col.name)} <i className="icon-play-filled"></i>
                                </button>

4 个答案:

答案 0 :(得分:1)

嗯,使用react的setState方法很容易解决。 您需要进行以下更改

  1. <button id= {"run"+col.name} type="button" onClick={() => this.onClickRun(col.name)} <i className="icon-play-filled"></i> 替换为

<button id= {"run"+col.name} className={this.state.clickedButton === col.name ? 'cursorDisabled' : ''} disabled={this.state.clickedButton === col.name} type="button" onClick={() => this.onClickRun(col.name)} <i className="icon-play-filled"></i>;

    2。
onClickRun(params) {

    const url = `/api/${params}/run`;
    const id = "run"+params;
    return $.ajax({
        type: 'POST',
        url,
        processData: false,
        contentType: 'application/json',
        beforeSend :() =>{
           // $("#run"+params).classList.add("cursorDisabled");
           // $("#run"+params).attr('disabled',true);   
            document.getElementById(id).disabled = true;
            document.getElementById(id).classList.add('cursorDisabled');
            this.setState({
              clickedButton: params
            })             
        },
        success: (response) => {
            this.setState({
              clickedButton: ''
            })
            if(!response.error) {

                // toast({
                //     message: 'Pipeline ran successfully.',
                //     flavor: 'success',
                //     options: { timeOut: 5000 }
                // });
                //$("#"+params).classList.remove("cursorDisabled");
                //$("#run"+params).attr('disabled',false);
                document.getElementById(id).disabled = false;
                  document.getElementById(id).classList.remove('cursorDisabled'); 
                location.reload(true);
            }
        },
        error: (error) => {
            console.log("error");
            this.setState({
              clickedButton: ''
            })
        }
    });
}
  1. 使用添加新状态
state = {
  clickedButton: ''
}

你们都准备好了。

答案 1 :(得分:1)

仅在您的情况下使用反应状态。 这里的例子

const ajax = ({beforeSend, success}) => {
  beforeSend();
  setTimeout(success, 2000);
}

class Test extends Component {
  state = {
    isLoading: ''
  }
  handleClick = (params) => {
    ajax({
      beforeSend: () => {
        this.setState({isLoading: params})
      },
      success: () => {
        this.setState({isLoading: ''});
      }
    });
  }
  render() {
    const {isLoading} = this.state;
    return <div>
      <button disabled={isLoading === 'b1'} onClick={() => this.handleClick('b1')}>{isLoading === 'b1' ? '...loading' : 'b1'}</button>    
    <button disabled={isLoading === 'b2'} onClick={() => this.handleClick('b2')}>{isLoading === 'b2' ? '...loading' : 'b2'}</button>
    </div>
  }
}

codepen上的示例

但是更好的体系结构决策是为每个按钮创建单独的组件,并将isLoading设置为boolean

答案 2 :(得分:0)

html按钮具有禁用的属性。我看到您正在尝试设置它,但是我建议在按钮声明上使用该属性,并在该属性上使用react表达式来检查处于组件状态的变量。在处理程序中设置和删除状态。

如果您使用的是最新版本的react,则可以使用钩子轻松完成此操作。否则,调用this.setState

答案 3 :(得分:0)

更好的方法是使用Modal和redux-saga产生副作用。

1)单击按钮时,执行redux-saga将捕获的动作

2)redux-saga将显示带有加载图标的Modal,并进行ajax调用,然后等到ajax调用返回。

3)通话返回后,隐藏模式。

4)模态应不可点击。这样当用户进行ajax通话时,该用户将无法单击任何地方