**For loop inside `Render()`** The loop gets called each time the component re-renders, it's a `1280` pushes to an array and that can be a performance issue, you can set it in `componentDidMount` or even outside the class since it's not dependent on its data, Consider [Array.from][1] to create and fill the array without creating an intermediate one. const range = Array.from({length: 1280}, (_, i) => i); And since you're filling it with `int`s and the `select` value is an `int` you don't really need `parseInt`. **Using `document.querySelector` to read values** >Basically, you can't easily rely on the input field because the state needs to come from >the React app's state, not from the browser's idea of what the value should be. See more explanation in [this blog post][2]. You should instead use the state to store the values of the inputs. ( see code snippet below ) **Accessing the DOM using `document.querySelector`** >In React, we do not directly manipulate the actual DOM. Instead, we must manipulate the virtual representation and let React take care of changing the browser's DOM. Check [this article][3] for in depth explanation and this one for [different ways to access the DOM][4]. using `refs`, instead of doing `document.querySelector('video')`, you can add a `ref` like : `<video src={video} controls ref={video => this.video = video}/>` then use `this.video` to do what you would do with a regular html element. [Using html5 canvas with react][5] import React, { Component } from 'react'; import './App.css'; import video from './video.mp4'; import watermark from './watermark.png'; const range = Array.from({ length: 1280 }, (_, i) => i); class App extends Component { constructor() { super(); this.state = { select: 0, live: false, positionX: 0, positionY: 0, checked: false }; } componentDidMount() { const context = this.canvas1.getContext('2d'); context.drawImage(this.video, 0, 0, 720, 1280); context.drawImage(this.watermark, this.state.select, this.state.select); if (this.state.live) { this.setState({ image: canvas.toDataURL() }); } } render() { return ( <div className="app"> <video src={video} controls ref={video => this.video = video} /> <div> <div className="watermarkButton" style={{}}> <span className="watermarkButtonX">Watermark X <select className="positionX" onChange={value => this.setState({ select: value, positionX: value })} value={this.state.positionX}> {range.map(i => ( <option key={i} value={i}>{i}</option> ))} </select> </span> <span className="watermarkButtonY">Watermark Y <select className="positionY" onChange={value => this.setState({ select: value, positionY: value })} value={this.state.positionY}> > {range.map(i => ( <option key={i} value={i}>{i}</option> ))} </select> </span> <span>Live</span> <input type="checkbox" name="live" value={this.state.live} onChange={e => this.setState({ live: e.target.value })} /> </div> <button className="watermarkButton watermarkSubmit" onClick={() => { const context = this.canvas2.getContext('2d'); context.drawImage(this.video, 0, 0, 1280, 720); context.drawImage(this.watermark, this.state.positionX, this.state.positionY); this.setState({ image: canvas.toDataURL() }); }}> Watermark! </button> <canvas ref={canvas => this.canvas1 = canvas} width={1280} height={720} /> <canvas ref={canvas => this.canvas2 = canvas} width={1280} height={720} /> <img alt="watermarks" className="watermark" src={watermark} style={{ visibility: 'visible' }} ref={watermark => this.watermark = watermark} /> <img alt="watermarks" className="imageDisplay" height="405px" width="560px" src={this.state.image} /> </div> </div> ); } } export default App; [1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from [2]: https://www.peterbe.com/plog/onchange-in-reactjs [3]: https://www.fullstackreact.com/p/jsx-and-the-virtual-dom/ [4]: https://davidwalsh.name/get-react-component-element [5]: https://blog.cloudboost.io/using-html5-canvas-with-react-ff7d93f5dc76