Search code examples
javascriptreactjsreact-hookshtml5-canvas

Using HTML Canvas getContext() in React without useEffect hook?


I am currently trying to learn about the html canvas, following tutorials which just do the following with Vanilla JS:

const canvas = document.getElementById("#myCanvas");
const context = canvas.getContext("2d");

I tried to use the useRef hook in addition, because I am using React to build the same. It kept displaying errors, so I console logged the canvas value as follows and I keep getting "null":

import React, {useRef} from 'react';
import './App.css'

const Canvas = () => {
    const canvasRef = useRef(null);
    const canvas = canvasRef.current;
    console.log(canvas);  //LOGS "null"
    const context = canvas.getContext("2d"); //HENCE THIS PRODUCES ERROR "can't read getContext() of null"

    return (
        <canvas id = "myCanvas" ref = {canvasRef}>
            
        </canvas>
    );
};

export default Canvas;

I have come across some solutions that use the useEffect hook. But I have heard that using useEffect might not be a good practice in React coding.

Moreover, those examples put almost all of the canvas coding inside the useEffect hook! That certainly feels like bad code design.

Is there any other way to go about this?


Solution

  • During the first render, canvasRef.current is null. This is because the canvas doesn't exist yet. You must finish rendering, then react must update the dom, and then react will assign the canvas element to canvasRef.current.

    You need to wait until that has happened to run your code. The way to run code after a render completes is with useEffect, so that's where you should put your code.

    But I have heard that using useEffect might not be a good practice in React coding.

    People do overuse it, but it has its uses. This is one of them.

    Here's react's documentation on when you might not need a useEffect: https://react.dev/learn/you-might-not-need-an-effect