首页 > 解决方案 > React:如何在单击后添加微调器,并在动画完成后更改屏幕

问题描述

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

我还有一个最佳实践问题。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>
    

标签: javascriptreactjs

解决方案


为您的状态添加一个布尔值并将其设置为 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>


推荐阅读