Search code examples
javascriptreactjshtml5-canvas

Use parent component's ref in react


I am creating a top-down game to learn react.

All of the drawing is in the Canvas component at the moment. My goal was to seperate each game element's drawing into it's own component, but I cannot access the parent element's ref inside of my child components.

Here is the current state of my code:

Canvas.jsx

import { useRef, useEffect} from 'react'
import Background from './Background'
import Player from './Player'

function Canvas() {
    let myCanvasRef = useRef(null)
    let myCanvas = null
    let context = null

    let background = new Image()
    background.src = 'src/assets/PelletTown.png'

    let player = new Image()
    player.src = 'src/assets/playerRight.png'

    useEffect(()=>{
        myCanvas = myCanvasRef.current
        context = myCanvas.getContext('2d')

        myCanvas.width = 1024
        myCanvas.height = 576
        context.fillStyle = 'black'
        context.fillRect(0, 0, myCanvas.width, myCanvas.height)

        background.onload = function() {
            context.drawImage(background, -700, -500)
            context.drawImage(player, 0, 0)
        }
    })

    return (
        <canvas ref={myCanvasRef}>
            <Background/>
            <Player/>
        </canvas>
    )
}

export default Canvas

and here is one of my child components:

Player.jsx

import { useRef, useEffect, forwardRef } from "react";

const Player = forwardRef((props, ref)=>{
    console.log(ref);
})

export default Player

Solution

  • This should be pretty simple, no need to use forward ref for passing a ref to the child, it can be passed as a normal prop as well. forwardRef is useful when you need to use ref from a child into the parnet:

    Canvas.jsx

    function Canvas() {
        let myCanvasRef = useRef(null)
     
     // your other code....
     // ...
     // ...
     
     return (
            <canvas ref={myCanvasRef}>
                <Background/>
                <Player canvasRef={myCanvasRef}/>
            </canvas>
        )
    }
    
    export default Canvas
    

    Player.jsx

    import { useRef, useEffect } from "react";
    
    const Player = (props)=>{
        console.log(props.canvasRef);
    }
    
    export default Player