如何让这个按钮重置这个反应组件中的计时器?

时间:2017-05-17 00:50:04

标签: javascript reactjs es6-class

我在ES6中有以下基本的ReactJS设置。当我按下重置按钮时,定时器不会回到“0”。我究竟做错了什么?我对React很陌生,所以任何代码组织和其他技巧也都很受欢迎。

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      seconds: 0
    }
    this.resetTimer.bind(this)
  }
  resetTimer = () => {
    this.setState({seconds: 0})
  }
  render() {
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Welcome to React</h2>
        </div>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
        <Button label="Start"/>
        <Button label="Stop"/>
        <Button label="Reset" onClick={this.resetTimer} />
        <Timer seconds={this.state.seconds} />
      </div>
    );
  }
}

class Button extends Component {
  render() {
    return(
      <div>
        <button onClick={this.props.onClick} >{this.props.label}</button>
      </div>
    );
  }
}

class Timer extends Component {
  constructor(props) {
    super(props)
    this.state = {
      seconds: this.props.seconds
    };
  }
  componentDidMount() {
    this.timerId = setInterval(
      () => this.tick(),
      1000
    );
  }
  tick() {
    this.setState({ seconds: this.state.seconds + 1});
  }
  componentWillUnmount() {
    clearInterval(this.timerId);
  }
  render() {
    return (
      <div>{secToMin(this.state.seconds)}</div>
    );
  }
}

export default App;

2 个答案:

答案 0 :(得分:1)

您的代码中存在的问题是,您只需将seconds道具值分配给构造函数中的state。构造函数只被调用一次,之后,对seconds prop的更改不会更新Timer组件的状态。

因此,当道具变更时,您需要手动更新状态。您可以使用componentWillReceiveProps()生命周期方法执行以下操作。

componentWillReceiveProps(nextProps){
  this.state = {
    seconds: nextProps.seconds
  };
}

此外,您实际上并不需要将this绑定到resetTimer,因为resetTimerarrow function。因此,您可以安全地从构造函数中删除this.resetTimer.bind(this)行。

答案 1 :(得分:0)

有两种方法可以将this正确绑定到resetTimer;

第一个选项是您在构造函数

中执行此操作
constructor(props) {
  super(props)
  this.state = {
    seconds: 0
  }
  this.resetTimer = this.resetTimer.bind(this)
}

并按照<Button label="Reset" onClick={this.resetTimer} />

设置您的按钮

第二种方法是根本不在构造函数中包含this.resetTimer,并在按钮上执行此操作<Button label="Reset" onClick={this.resetTimer.bind(this)} />

有两种方法可以将this正确绑定到resetTimer;

第一个选项是您在构造函数

中执行此操作
constructor(props) {
  super(props)
  this.state = {
    seconds: 0
  }
  this.resetTimer = this.resetTimer.bind(this)
}

并按照<Button label="Reset" onClick={this.resetTimer} />

设置您的按钮

第二种方法是根本不在构造函数中包含this.resetTimer,并在按钮上执行此操作<Button label="Reset" onClick={this.resetTimer.bind(this)} />

你有第二个问题。您的按钮组件可能无法正常工作,因为您的道具未设置。

在Button构造函数中执行以下操作:

 constructor(props) {
   super(props);
 }

或者将按钮更改为无状态组件并按如下方式编写:

function Button({onClick, label}) {
    return (
      <div>
        <button onClick={onClick} >{label}</button>
      </div>
    );
}

第三个问题可能出在你的resetTimer函数上。

  resetTimer() {
    this.setState({seconds: 0})
  }

尝试像上面那样写它,看看是否有效。