首页 > 解决方案 > 你如何在 React JS 中重置加载栏?

问题描述

这里只是一个快速的问题。正在完成我之前在这里问过的一个项目(如何在 React JS 中的组件之间传递值?)并且还有另一个问题。在这里的机器组件中我需要一个加载栏,老师给我们展示了这个作为示例:https ://codepen.io/AaronCoding/pen/GjVaGp 。我已经对其进行了修改,因此它在按下值而不是按下按钮时起作用,但我需要将其重置,因此当用户按下另一个按钮时,它会再次“加载”。我曾尝试将进度变量设置为 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;

标签: reactjsanimation

解决方案


通过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;

推荐阅读