单击按钮时的加载指示器(react.js和ant设计)

时间:2019-07-09 10:03:03

标签: reactjs

我做了一个按钮,单击后将其标签从“提取”更改为“提取”,然后将其禁用。我现在想做的是单击它时有一个加载指示器,而禁用按钮时则停止。

我尝试了

document.getElementById(inputID).setAttribute(“ loading”,“ true”);

当单击按钮但发现它不适用于按钮时。我现在还在尝试将setState与

一起使用

document.getElementById(“ btnTesting”)。innerHTML =“ EXTRACTED”;

class DashboardPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
    }
  onClickBtn = () => {
    this.setState({ loading: true});
    document.getElementById("btnTesting").innerHTML = "EXTRACTED";
    document.getElementById("btnTesting").setAttribute("disabled","true");
  }
    render() {
       return (
          <Button id="btnTesting" onClick={this.onClickBtn} loading={this.state.loading}>EXTRACT</Button>
       )
    }
  }

我希望单击时会有一个加载指示器,然后在禁用按钮时停止。但是屏幕变成空白。我在控制台中看到了此错误

未捕获的DOMException:无法在“节点”上执行“ insertBefore”:要在其之前插入新节点的节点不是该节点的子节点。

上述错误发生在组件中: 等等。 等等。

未捕获的DOMException:无法在“节点”上执行“ insertBefore”:要在其之前插入新节点的节点不是该节点的子节点。

3 个答案:

答案 0 :(得分:0)

因为使用的是React,所以不需要使用innerHTMLsetAttribute来更改按钮文本或禁用状态。

您可以使用状态变量buttonText(初始化为“提取”)和isDisabled(初始化为false),并且可以在按钮完成执行后更改状态。

class DashboardPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
      buttonText: "EXTRACT",
      isDisabled: false
    };
  }
  onClickBtn = () => {
    this.setState({ loading: true });
    setTimeout(() => {
      this.setState({
        buttonText: "EXTRACTED",
        isDisabled: true,
        loading: false
      });
    }, 2000);
  };
  render() {
    return (
      <Button
        id="btnTesting"
        onClick={this.onClickBtn}
        loading={this.state.loading}
        disabled={this.state.isDisabled}
      >
        {this.state.buttonText}
      </Button>
    );
  }
}

我添加了一个2000ms的setTimeout,以便您可以看到加载指示器。

在此处找到演示:https://codesandbox.io/s/antd-reproduction-template-l1d4r

答案 1 :(得分:0)

您可以检查以下代码是否解决了您的问题?我添加了计时器来演示时间影响,以便使加载变得明显。

使用ReactJS,您不必使用setAttribute或innerHTML,因为ReactJS使用virtualDOM。即使使用它们,也可能会使DOM处于不一致状态。按照标准的React惯例,您应该使用状态变量来处理您的要求(即更改DOM)

class DashboardPage extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        loading: {"btn1": false},
        disabled: false,
        buttonText: 'Extract'
      }
    onClickBtn = (btnStr) => {
      let loadingCopy = Object.assign({},this.state.loading)
      loadingCopy[btnStr] = true
      this.setState({loading: loadingCopy})
      setInterval(() => {
        loadingCopy[btnStr] = false
        this.setState({ loading: loadingCopy, buttonText: 'Extracted', disabled: true });
        }, 3000);
    }
    render() {
       return (
          <ButtononClick={() =>this.onClickBtn("btn1")} loading={this.state.loading["btn1"]} disabled={this.state.disabled}>{this.state.buttonText}</Button>
         )
    }
}

答案 2 :(得分:0)

import { Button } from 'antd';
import React from "react";

class SubmitButton extends React.Component {
state = {
    loadings: [],
};

enterLoading = index => {
    this.setState(({loadings}) => {
        const newLoadings = [...loadings];
        newLoadings[index] = true;

        return {
            loadings: newLoadings,
        };
    });
};

render() {
    const {loadings} = this.state;
    return (
        <>
            <Button type="primary" htmlType="submit" loading={loadings[0]} onClick={() => this.enterLoading(0)}>
                Submit
            </Button>
        </>
    );
}

代码: https://codesandbox.io/s/withered-framework-w5lmc?file=/src/App.js