Search code examples
javascriptreactjshtml5-canvasphaser-framework

Phaser 3 - Duplicate Canvas component is created when creating a new instance of Phaser 3 GameObject in React


I'm using Create React App as framework and trying to render the GameObject new Phaser.Game(gameConfig) as React component. I am able to render but it creates a duplicate Canvas object as shown below: enter image description here

Here is my Game Component:

import Phaser from "phaser";
import React from "react";

export default class Game extends React.Component {
    componentDidMount() {
        const gameConfig: Phaser.Types.Core.GameConfig = {
            type: Phaser.AUTO,
            parent: 'game-container',
            backgroundColor: '#EBEBEB',
            width: 600,
            height: 800
        }

        new Phaser.Game(gameConfig);
    }

    shouldComponentUpdate() {
        return false;
    }

    render() {
        return <div id='game-container' />   
    }
}

And here is where I'm rendering:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import reportWebVitals from './reportWebVitals';
import Game from './game';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <React.StrictMode>
    <Game />
  </React.StrictMode>
);

reportWebVitals();

How do I remove this duplicate?


Solution

  • I assume the problem could be, that due to the <React.StrictMode> Tag, that the function componentDidMount, might be executed twice. If you remove this tag, the function will not be execute twice.
    And since each call of componentDidMount creates a new phaser gameobject, due to the new Phaser.Game(...) call. Which in turn creates a new canvas.

    Since the Tag <React.StrictMode> is not really needed for production, you can remove it without problems/changes to your UI output.

    <script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.min.js"></script>
    <script src="https://unpkg.com/react/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    
    <div id="root"></div>
    
    <script type="text/babel">
        class Game extends React.Component {
            componentDidMount() {
                const gameConfig = {
                    type: Phaser.AUTO,
                    parent: 'game-container',
                    backgroundColor: '#EBEBEB',
                    width: 300,
                    height: 120,
                    scene: {create(){ this.add.text(150,60, 'GAME').setFontFamily('Arial').setFontSize(80).setOrigin(.5).setColor('#000000')}}
                }
    
                new Phaser.Game(gameConfig);
            }
    
            shouldComponentUpdate() {
                return false;
            }
    
            render() {
                return <div id='game-container' /> 
            }
        }
    
        const root = ReactDOM.createRoot(document.getElementById('root'));
        // creates two canvas elements
        root.render( <React.StrictMode><Game /></React.StrictMode> );
        // creates one canvas elements
        root.render( <Game /> );
    </script>