如何包装一个handleClick around reactjs调用

时间:2018-02-12 20:20:04

标签: javascript reactjs

我正在尝试建立一个赛马应用程序并且是新的反应,当用户点击骑师的“开始”按钮进行比赛时,我正在努力处理点击事件。当我删除handleClick功能时(如下面所述),当我重新加载页面时,骑师会自动比赛(使用react的进度条)。当我点击“开始”按钮时,我只想要这个功能。

App.js

import React, { Component } from 'react';
import Progress from 'react-progressbar';
import logo from '../../images/logo.svg';
import './App.css';


class Jockey extends Component {
  state = {
    interval: Math.floor(Math.random() * 500),    
    progress: 5,
  }

  // handleClick = () => {
    // console.log('The link was clicked.');
    componentDidMount = () => {
      this.interval = setInterval(this.timer, this.state.interval);
    }

    timer = () => {
      this.setState({ progress: this.state.progress + 1 });
      // (this.state.progress >= 99) ? this.setState({ progress: 100 }) : "" ;
      if(this.state.progress >= 99) {
         this.setState({ progress: 100 }) 
      };
    }

  // } 

  render() {
    const Buttons = () => (
      <div className="App-buttons">
        <button className="ui primary button" onClick={this.handleClick}>Start</button>
        <button className="ui button">Reset</button>
      </div>
    );

    return (
      <div>
        <Buttons />
        <div className="App-field">
          <h1>Race Track</h1>
          <img src="https://avatars1.githubusercontent.com/u/3757315?v=4" alt=""/>
          <Progress className="App-progress" completed={this.state.progress}/>
          
        </div>
      </div>
    );
  }

}

export class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to the React Race Hustle</h1>
        </header>
        <Jockey />
      </div>
      
    );
  }
}

2 个答案:

答案 0 :(得分:3)

使用您的代码(注释掉handleClick),componentDidMount()函数将在组件安装时自动运行。这意味着当组件安装时,timer()将在定义的时间间隔内开始运行。

您需要进行两项更改:

  1. timer()移至处理程序
  2. componentDidMount()功能移到处理程序外
  3. handleClick = () => {
      console.log('The link was clicked.');
      this.interval = setInterval(this.timer, this.state.interval);
    
      timer = () => {
        this.setState((prevState) => ({ progress: (prevState.progress + 1 > 98 ? 100 : prevState.progress + 1) });
      }
    }
    

    我们不再需要componentDidMount()功能。

答案 1 :(得分:2)

我尝试更改您的代码,以满足您的需求;希望你能看到它所需的一些变化。

import React from 'react';
import ReactDOM from 'react-dom';
import Hello from './Hello';


class Jockey extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      interval: Math.floor(Math.random() * 500),
      progress: 5,
    }
    this.handleClick=this.handleClick.bind(this);
  }

  handleClick (){
    let that = this;
    this.interval = setInterval(function () {
      that.setState((ps)=>{ 
        if(ps.progress + 1>=99) return {progress:100}
        return {progress: ps.progress + 1 }}
        );

    }, this.state.interval);
  }



render() {
  const Buttons = () => (
    <div className="App-buttons">
      <button className="ui primary button" onClick={this.handleClick}>Start</button>
      <button className="ui button">Reset</button>
    </div>
  );

  return (
    <div>
      <Buttons />
      <div className="App-field">
        <h1>Race Track</h1>
        <img src="https://avatars1.githubusercontent.com/u/3757315?v=4" alt="" />
        <div className="App-progress" completed>{ this.state.progress }</div>

    </div>
      </div >
    );
}

}

ReactDOM.render(
  <Jockey />,
  document.getElementById('root')
);

一些意见:

  • 我也使用了functional setState;因为当状态依赖于先前状态的值时,你所拥有的不是设置状态的正确方法。

  • 您也可以在卸载组件时调用clearInterval

  • 我在div中代替Progress组件进行了渲染。

  • 我不会将interval置于州内;如果没有在渲染中使用,你通常不会把东西放进州。