1

I'm trying to useRef to get a refenrece to the canvas but typescript is complaining

import React, { useRef } from 'react';
const AddPhoto: React.FC = () => {
  const canvas = useRef<HTMLCanvasElement>(null);
  const ctx: CanvasRenderingContext2D = canvas.getContext('2d')!;
//                                                 ^ error
}
  return (
      <canvas
          ref={canvas}
          width={315}
          height={315}
     />
)

The error I get is

Property 'getContext' does not exist on type 'RefObject<HTMLCanvasElement>'.ts(2339)

if I change it to

    if (canvas && canvas.current) {
      const ctx: CanvasRenderingContext2D = canvas.current.getContext('2d');
//           ^error

    }

the error is now

Type 'CanvasRenderingContext2D | null' is not assignable to type 'CanvasRenderingContext2D'.
  Type 'null' is not assignable to type 'CanvasRenderingContext2D'.ts(2322)
Bill
  • 4,614
  • 13
  • 77
  • 132
  • try: [he purpose of Typescript is to avoid wrong types. By default document.getElementById returns a HTMLElementtype which is a generic type. In order to make your app understand it is a canvas element you need to cast it using syntax.](https://stackoverflow.com/a/58218739/7943013) – Litaf Kupfer Jun 14 '21 at 13:49

1 Answers1

2

As you use useRef, your value stores not just in canvas variable, but in canvas.current, so you should use canvas.current.getContext('2d').


To fix type problem, use this instead of if(...){...}

const ctx: CanvasRenderingContext2D | null = canvas.current ? canvas.current.getContext('2d') : null;
boikevich
  • 398
  • 2
  • 9
  • 1
    Or use: `canvas.current?.getContext('2d')` so you can omit the ternary. – raarts Apr 24 '20 at 06:48
  • 1
    If acoiding the ternary, you would have to use ```const ctx: CanvasRenderingContext2D | null | undefined = canvas.current?.getContext("2d")``` – Michael Murphy Jun 21 '20 at 12:28