import React, {Component} from 'react'; interface AppState { color: string; } class App extends Component<{}, AppState> { canvasRef: React.RefObject; constructor(props: {}) { super(props); this.state= { color: "blue" } // 2 - We create an empty ref object and store it in our variable this.canvasRef = React.createRef(); } updateCanvasImage() { console.log("inside updateCanvasImage"); // 5 - We can then access the canvas that was put into the webpage, to draw some content on it let canvas = this.canvasRef.current; if (canvas === null) return; // Canvas objects use a "graphics context" for drawing - so we need to get the "2d drawing" context // Canvases also support other kinds of drawing, like 3D, which is why they use contexts to separate them out let context = canvas.getContext("2d"); if (context === null) return; // Contexts work by setting up some fields on them (like the fill color - fillStyle), then calling methods context.fillStyle = this.state.color; context.fillRect(50, 50, 150, 100); } componentDidMount() { console.log("inside componentDidMount"); // 4 - When the things we returned from render are added to the webpage by React, it will call componentDidMount() this.updateCanvasImage(); } componentDidUpdate() { console.log("inside componentDidUpdate"); this.updateCanvasImage(); } // For things like button handlers, we need to use arrow functions instead of regular functions. // The rule: Any time you pass a function as a value to something else, that function needs to // be an arrow function. handleButtonClick = () => { alert("Ouch!"); // alert() is built into browsers - displays a pop-up message }; makeRed = () => { console.log("setState is being called"); this.setState({ color: "red" }); }; makeBlue = () => { console.log("setState is being called"); this.setState({ color: "blue" }); }; render() { console.log("inside render"); return (

Selected Color: {this.state.color}

); } } export default App;