如何在React JS中重置加载栏?

时间:2018-10-18 20:16:23

标签: reactjs animation

这里只是一个快速的问题。正在完成我之前在这里问过的一个项目(How to pass values between components in React JS?),还有另一个问题。在这里的机器组件中,我需要一个加载栏,老师向我们展示了此示例:https://codepen.io/AaronCoding/pen/GjVaGp。我已经对其进行了修改,因此当按下值而不是按下按钮时它可以工作,但是我需要重置它,以便当用户按下另一个按钮时它再次“加载”。我尝试将progress变量设置为0,但这似乎导致加载栏陷入循环。

import React, { Component } from 'react';

class CoffeeMachine extends Component {

    state = {
        brewing: "Now Brewing: Nothing",
        progress: 0,
        speed: 1,
        color: "#ff0050",
        frame: this.frame.bind(this),
        green: this.green.bind(this),
        red: this.red.bind(this)
    }



    frame() {
        if (this.state.progress < 100){
            this.setState((prevState, props) => ({
                progress: prevState.progress + this.state.speed,
                color: "#" + this.red() + this.green() + "50"
            }));
            console.log(this.state.color);


        }
    }

    componentWillUnmount() {
        clearInterval(this.interval);
    }

    green() {
        let progress = this.state.progress;
        progress *= 2.55;
        progress = Math.round(progress);
        progress = progress.toString(16);
        return progress;
    }

    red() {
        let progress = this.state.progress;
        progress *= 2.55;
        progress = Math.round(progress);
        progress = 255 - progress;
        progress = progress.toString(16);
        return progress;
    }



    brewCoffee() {
        this.setState({brewing: "Now brewing: " + this.props.coffee})
        setTimeout(() => {this.brewingComplete()}, 5000);
        this.interval = setInterval(() => this.frame(), 50);
    }

    brewingComplete() {
        this.setState({brewing: this.props.coffee + " is done"})
        setTimeout(() => {this.brewingComplete()}, 5000);
    }

    componentWillUpdate(nextProps,nextState) {
        if (this.props.coffee !== null && this.state === nextState) {
            setTimeout(() => {this.brewCoffee()}, 3000);
        }

    }


    render(){
        return(

            <div>
            { this.state.brewing}
    <div id="myBar" style={{
            width: this.state.progress + "%",
                backgroundColor: this.state.color
        }}>
    <div id="label">Loaded {this.state.progress}%</div>
        </div>
            </div>



        )
}
}

export default CoffeeMachine;

1 个答案:

答案 0 :(得分:1)

在您的componentWillUpdate()中,检查进度是否等于零,以确保没有进行冲泡。

您还应该检查其中要冲泡的咖啡的选择是否已更改。

然后您可以清除间隔并将进度设置为零。

请确保您说冲泡确实完成了,因为超时仍在继续。

此外,您不能在状态中绑定方法。您可以使用粗箭头直接绑定它们,也可以将它们绑定到构造函数中(老式)。

我还建议将brewingDelay和brewingTime存储在const中,因为它们多次用于必须“同步”的事务。

import React, { Component } from "react";

const brewingDelay = 2000;
const brewingTime = 5000;
const initialColor = "#ff0050";

class CoffeeMachine extends Component {
  state = {
    brewing: "Now Brewing: Nothing",
    progress: 0,
    speed: 1,
    color: initialColor,
    frame: null,
    green: null,
    red: null
  };

  frame = () => {
    if (this.state.progress < 100) {
      this.setState((prevState, props) => ({
        progress: prevState.progress + this.state.speed,
        color: "#" + this.red() + this.green() + "50"
      }));
      console.log(this.state.color);
    }
  };

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  green = () => {
    let progress = this.state.progress;
    progress *= 2.55;
    progress = Math.round(progress);
    progress = progress.toString(16);
    return progress;
  };

  red = () => {
    let progress = this.state.progress;
    progress *= 2.55;
    progress = Math.round(progress);
    progress = 255 - progress;
    progress = progress.toString(16);
    return progress;
  };

  brewCoffee = () => {
    this.setState({ brewing: "Now brewing: " + this.props.coffee });
    setTimeout(() => {
      this.brewingComplete();
    }, brewingTime);
    this.interval = setInterval(() => this.frame(), 50);
  };

  brewingComplete = () => {
    if (this.state.progress >= 99)
      this.setState({ brewing: this.props.coffee + " is done" });
    setTimeout(() => {
      this.brewingComplete();
    }, brewingTime);
  };

  componentWillUpdate(nextProps, nextState) {
    if (
      this.props.coffee !== undefined &&
      nextProps.coffee !== this.props.coffee &&
      this.state.progress !== 0
    ) {
      clearInterval(this.interval);
      setTimeout(() => {
        this.setState({ progress: 0, color: initialColor }, () => {});
      }, brewingDelay);
    }
    if (this.props.coffee !== null && this.state === nextState) {
      setTimeout(() => {
        this.brewCoffee();
      }, brewingDelay);
    }
  }

  render() {
    return (
      <div>
        {this.state.brewing}
        <div
          id="myBar"
          style={{
            width: this.state.progress + "%",
            backgroundColor: this.state.color
          }}
        >
          <div id="label">Loaded {this.state.progress}%</div>
        </div>
      </div>
    );
  }
}

class ParentChoice extends React.PureComponent {
  state = {};
  render() {
    return (
      <React.Fragment>
        <button onClick={() => this.setState({ coffee: "Arabica" })}>
          Arabica
        </button>
        <button onClick={() => this.setState({ coffee: "Robusta" })}>
          Robusta
        </button>
        <CoffeeMachine coffee={this.state.coffee} />
      </React.Fragment>
    );
  }
}

export default ParentChoice;