1

I have a Vue component that works just fine. Now I'm trying to convert that code to ReactJS equivalent. My attempt on React

 var ticksArray = Array.apply(null, {length: 27}).map(Number.call, Number);
 export default class Timer extends Component {
 constructor(props) {
  super(props);
  this.state = {
    angle:250,
    minangle:0,
    maxangle:270,
    xDirection:"",
    yDirection:"",
    oldX:0,
    dragging: false
  }
}
onMousedown(){
  this.setState({dragging : true});
}
onMouseup(){
  this.setState({dragging : false});
}
onMousemove(e){
    if(!this.state.dragging)
      return;
    this.setState({
      xDirection : this.state.oldX < e.pageX ? 'right' : 'left',
      oldX:e.pageX,
      yDirection: this.state.xDirection === 'left' ? 'down' : 'up'
    });
    if(this.state.yDirection === 'up' && this.state.angle + 2 <= 
    this.state.maxangle)
        this.setState({angle:this.state.angle += 2})
    else if(this.state.yDirection === 'down' && this.state.angle - 2 >= 
    this.state.minangle)
        this.setState({angle:this.state.angle -= 2})
}
knobStyle(){
  return {
    'transform':'rotate('+this.state.angle+'deg)'
    }
}
activeTicks(){
  return (Math.round(this.state.angle / 10) + 1);
}
currentValue(){
  return Math.round((this.state.angle/270)*100) + '%'
}
componentDidMount(){
  document.addEventListener('mouseup',this.state.onMouseup)
  document.addEventListener('mousemove',this.state.onMousemove)
}
render() {
    var tickDivs = ticksArray.map(function(item) {
        return (
            <div key={item} className="tick"></div>
        );
    });
    return (
        <div id="timer">
            <div className="knob-surround">
                <div className="knob"></div>
                <span className="min">Min</span>
                <span className="max">Max</span>
                <div className="ticks" className="n <= activeTicks ? 
    'activetick' : ''">
                    {tickDivs}
                </div>
            </div>
        </div>
    );
  }
}

It's not working. I'm missing something. I'm assuming the problem lies in this code bit.

<div className="ticks" className="n <= activeTicks ? 
        'activetick' : ''">

Please help fix this.

1
  • 1
    React uses the following syntax: className={n <= activeTicks ? 'activetick' : ''} Commented May 2, 2017 at 8:50

1 Answer 1

2

Add this here instead of comment:

  1. React uses the following syntax:

    className={n <= activeTicks ? 'activetick' : ''}

  2. In componentDidMount you assign handlers in a wrong way, should be like:

    document.addEventListener('mouseup', this.onMouseup)

    Note here that handler is not a part of your state. And the corresponding definition of the handler:

    private onMouseup = () => {...}

    The reason to store reference for the event handler instead of having class method - see in #3

  3. Do not forget to unsubscribe your event handlers in componentWillUnmount like this:

    window.removeEventListener("mouseup", this.onMouseup);

UPDATE:

Here is an example working without using arrow functions: https://jsfiddle.net/6dnrLw4n/4/

Sign up to request clarification or add additional context in comments.

8 Comments

I'm getting a Syntax error. webpackHotDevClient.js:233 Error in ./src/components/Timer.js Syntax error: C:/Users/admin/Documents/GitHub/....../Timer.js: Unexpected token (19:12) 17 | this.setState({dragging : true}); 18 | } > 19 | private onMouseup() =>{ | ^ 20 | this.setState({dragging : false}); 21 | } 22 | onMousemove(e){ @ ./src/App.js 16:13-42
Are you sure you have not missed = sign after onMouseup, like I has wrote above: private onMouseup = () => {...}
I changed it back to onMouseup () {...} and now I'm getting Uncaught TypeError: Cannot read property 'dragging' of undefined at onMousemove (Timer.js:23)
That is because in that way you are loosing 'this'. Use arrow functions to keep it (or alternatively bind - but I would stick to arrow functions)
Same issue.. Error in ./src/components/Timer.js Syntax error: C:/Users/admin/Documents/GitHub/............/Timer.js: Unexpected token (19:12) 17 | this.setState({dragging : true}); 18 | } > 19 | private onMouseup = () =>{ | ^ 20 | this.setState({dragging : false}); 21 | } 22 | onMousemove(e){ @ ./src/App.js 16:13-42
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.