Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
394 views
in Technique[技术] by (71.8m points)

javascript - React:单击后如何添加微调器,动画完成后如何更改屏幕(React: how to add a spinner after click, and change screen after the animation completes)

I saw there are already answered questions on how to add spinners during fetch requests.

(我看到已经存在有关在获取请求期间如何添加微调器的问题。)

However what I need is to stop showing the animation when the animation completes.

(但是,我需要的是在动画完成后停止显示动画。)

The animation completes after the timeout is reached.

(达到超时后,动画将完成。)

Also I have a best practice question.

(我也有一个最佳实践问题。)

It's a good practice to empty the resources on componentWillUnmount and clear there the timeout.

(清空componentWillUnmount上的资源并清除超时是一个好习惯。)

In the code below I clear the timeout in a if condition, because it has to stop as the height of the element reaches the right level.

(在下面的代码中,我清除了if条件下的超时,因为它必须在元素的height达到正确水平时停止。)

Is that ok as I did it?

(可以像我一样吗?)

If now, how should it look like to have the same functionality in the componentWillUnmount lifecycle phase?

(如果现在,在componentWillUnmount生命周期阶段应该具有相同的功能?)

Here is the animation Component:

(这是动画组件:)

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]
            )
        }
    };

And here is the Component that has to appear after the animation disappears.

(这是动画消失后必须出现的组件。)

The steps are like this:

(步骤如下:)

  1. A user enter and uses this tool

    (用户输入并使用此工具)

  2. The user clicks "calculate"

    (用户单击“计算”)

  3. The animation appears instead or on top of the tool

    (动画出现在工具上方或上方)

  4. When the animation completes, the animation Component disappears and the tool is once again visible with its updated state (results of the calculation).

    (动画完成后,动画组件消失,并且该工具及其更新状态(计算结果)再次可见。)

      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> 
  ask by Pikk translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Add a boolean to your state and set it to false, when the user clicks the button set it to true, after doing the calculation set it to false.

(将布尔值添加到您的状态并将其设置为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
  });
};

Example

(例)

 <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> 


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...