1

I am trying to create a pattern animation using react and canvas. When the component loads, I trigger the animation in the componentDidUpdate method but after executing one frame, react throws the error in the move function: Uncaught TypeError: Cannot read properties of undefined (reading 'x')

Code :

export default class Canvas extends Component {
    
    constructor(props) {
        super(props);
        this.canvasRef = createRef();
        this.width = parseInt(this.props.width);
        this.height = parseInt(this.props.height);
        this.x = Math.random(this.props.seed) * this.width;
        this.y = Math.random(this.props.seed) * this.height;
        this.r = Math.random(this.props.seed) * 20 + 5;
        this.dx = 10;
        this.dy = 10;
        this.color = "#"+Math.floor(Math.random(this.props.seed) * 1000000);
    }
    
    componentDidMount () {
        console.log("initial view created");
        this.ctx = this.canvasRef.current.getContext('2d');
    }

    componentDidUpdate () {
        console.log("updating view");
        this.move();
    }

    draw () {
        this.ctx.fillStyle = this.color;
        this.ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
        this.ctx.fill();
    }

    
    //this is the function where the problem might be :
    move() {
        console.log(this.x, this.y);
        this.x += this.dx; //this line propmpts the error
        this.y += this.dy;
        this.draw();
        
        requestAnimationFrame(this.move)
    }

    render() {
        return (
            <canvas
                ref={this.canvasRef}
                className={this.props.className}
                width={this.props.width}
                height={this.props.height}
            />
        );
    }
}

I have tried running the function move in a loop without the requestAnimationFrame() and the code runs, so I doubt the problem has something to with react or the class component. I think it might be relared to the requestAnimationFrame() but I cannot understand what could the problem be.

Ahan
  • 73
  • 5

1 Answers1

2

Try defining move using an arrow function as follows:

move=()=> {
    console.log(this.x, this.y);
    ...
}

Using an arrow method, ensures that the method does not have its own this & uses the current object as this.

Nice Books
  • 1,675
  • 2
  • 17
  • 21