javascript - react : how to add a spinner after click, 并在动画完成后更改屏幕

标签 javascript reactjs

我看到已经回答了有关如何在获取请求期间添加微调器的问题。 然而,我需要的是在动画完成时停止显示动画。达到超时后动画完成。

我还有一个最佳实践问题。 最好清空 componentWillUnmount 上的资源并清除超时。在下面的代码中,我清除了 if 条件下的超时,因为当元素的 height 达到正确的水平时它必须停止。

像我那样可以吗?如果现在,在 componentWillUnmount 生命周期阶段拥有相同的功能应该是什么样子?

这是动画组件:

class Thermometer extends Component {

    state = {
        termFill : 0
    };

        componentDidMount() {
            const interval = setInterval(() => {
                this.setState({
                    termFill: this.state.termFill + 10
                });
                if (this.state.termFill === 110) {
                    window.clearInterval(interval);
                }
            }, 200)
        }



        render() {
            const styles = {
              height: `${this.state.termFill}px`
            };


            if (this.state.termFill < 100) {

                return (
                    <section>
                                <div id="therm-fill" style={styles} />
                      [MORE CODE - SHORTENED FOR EASIER READING]
            )
        }
    };

这是动画消失后必须出现的组件。 步骤是这样的:

  1. 用户进入并使用该工具
  2. 用户点击“计算”
  3. 动画出现在工具上方或代替工具
  4. 动画完成后,动画组件消失,工具 再次可见其更新状态(结果 计算)。

     class DiagnoseTool extends Component {
        state = {
            [OTHER STATES REMOVED TO KEEP THE CODE SHORTER]
            wasBtnClicked: false
        };
    
            [OTHER RADIO AND CHECKBOX HANDLERS REMOVED TO KEEP THE CODE SHORTER]
    
    
    onButtonClick = e => {
        e.preventDefault();
        this.calculate();
    
        this.setState({
            wasBtnClicked: true
        })
    };
    
    
    addResult = () => {
    
        const resultColor = {
            backgroundColor: "orange"
        };
    
    
        let theResult;
            if (this..... [CODE  REMOVED TO HAVE THE CODE SHORTER]
            return theResult;
    };
    
    
    calculate = () => {
        let counter = 0;
        let radiocounter = 0;
    
        Object.keys(this.state).filter(el => ['cough', 'nodes', 'temperature', 'tonsillarex'].includes(el)).forEach(key => {
    
            // console.log(this.state[key]);
            if (this.state[key] === true) {
                counter += 1;
            }
        });
    
        if (this.state.radioAge === "age14") {
            radiocounter++
        } else if (this.state.radioAge === "age45") {
            radiocounter--
        }
    
        if (this.state.radioAge !== "") {
            this.setState({
                isDisabled: false
            })
        }
    
        this.setState({
            points: counter + radiocounter
        });
    };
    
    
    
    render() {
        const {cough, nodes, temperature, tonsillarex, radioAge, wasBtnClicked} = this.state;
        return (
            <Container>
                <BackArrow />
    
                [JSX REMOVED TO KEEP THE CODE SHORTER]
    
                    <div className="resultbox">
                    {
                        (wasBtnClicked) && this.addResult()
                    }
                    </div>
                </div>
    
    
       [HERE IS THE BUTTON]
                <button
                    style={{height: "40px", width: "150px", cursor:"pointer"}}
                    type="submit"
                    className="calculateBtn"
                    onClick={this.onButtonClick}
                    disabled={!radioAge}
                >CALCULATE</button>
    
    
            </Container>
    

最佳答案

向您的状态添加一个 bool 值并将其设置为 false,当用户单击按钮时将其设置为 true,计算完成后将其设置为 false。

calculate = () => {
  let counter = 0;
  let radiocounter = 0;

  this.setState({
    isLoading: true // set is loading to true and show the spinner
  })

  Object.keys(this.state)
    .filter(el =>
      ["cough", "nodes", "temperature", "tonsillarex"].includes(el)
    )
    .forEach(key => {
      // console.log(this.state[key]);
      if (this.state[key] === true) {
        counter += 1;
      }
    });

  if (this.state.radioAge === "age14") {
    radiocounter++;
  } else if (this.state.radioAge === "age45") {
    radiocounter--;
  }

  if (this.state.radioAge !== "") {
    this.setState({
      isDisabled: false
    });
  }

  this.setState({
    points: counter + radiocounter,
    isLoading: false // set it to false and display the results of the calculation
  });
};

示例

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<div id="root"></div>

<script type="text/babel">

class App extends React.Component {

  timer = null;
  
  constructor() {
    super();
    this.state = {
      result: '',
      isLoading: false
    };
  }
  
  
  
  showContent = () => { this.setState({ isLoading: false, result: `7 + 5 = ${7 + 5}` })}
  
  
  calculate = () => {
  
     this.setState({
      isLoading: true,
      result: ''
     });
     
     this.timer = setTimeout(this.showContent, 5000);
  }
  
  componentWillUnmount = () => {
   clearTimeout(this.timer);
  }
  

  render() {

    return (
      <div>
      <p>7 + 5</p>
      <p>{this.state.result}</p>
      { this.state.isLoading 
        
        ? <p>Calculating...</p>
        : <button onClick={this.calculate}>Calculate</button>
      
      }
      </div>
    );
  }
}

ReactDOM.render(
    <App />,
    document.getElementById('root')
);
</script>

关于javascript - react : how to add a spinner after click, 并在动画完成后更改屏幕,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59095048/

相关文章:

javascript - Node.js Web 服务器中的并行请求

javascript - 溢出在哪里?

reactjs - 如何使用 turfjs 和 mapbox js 从方形网格中选择并突出显示单元格?

css - 模块 CSS 未加载到元素中

javascript - 我试图在 REACT 中加密密码,以便每个字母都将打印为星号 ` * `

javascript - React 中分离的 DOM 节点内存泄漏

javascript - Cordova/Phonegap 文件功能不起作用

javascript - 在 nodejs 中的 res.end() 之后重定向

php - jQuery AJAX POST 给出 undefined index

javascript - 在单独的渲染之间共享 React 组件逻辑