Using PIXI.js with React Functional Components/Hooks

I was looking to integrate PixiJS into a React app of mine. There are some interesting node packages out there like react-pixi-fiber that converts all of PixiJS’s objects into React components. This has some great applications but I wanted to start with vanilla PixiJS since my application is going to be adding and removing a lot of dynamic components. I found several articles online for using React’s class components but I couldn’t find any using functional components so I’ve decided to write one myself.

Installation

To install PixiJS in your project run one of the following:

# Using yarn
yarn add pixi.js

# Using npm
npm install pixi.js

Usage

First you will need to include PixiJS in your application. There are two ways of doing this:

// Import all of PixiJS and use like PIXI.Application
import * as PIXI from "pixi.js";

// Import just what you need from PixiJS
import { Application } form "pixi.js"

I think whichever you choose is personal preference. We need a DOM ref. For more information on refs see the React Documentation. In React class components you can create refs using React.createRef() and attached to React elements via the ref attribute. However, in Functional components you don’t have that option, instead you must React.useRef(). Here’s an example:

import React, { useRef } from "react";

function MyComponent() {
  const ref = useRef(null);

  return <div ref={ref} />;
}

Now that we have a DOM ref we can add PixiJS to it. I’m currently deciding between two routes of doing this that both have their pros and cons. I haven’t used it enough to decide which way I’ll be doing it but I’ve included both ways here.

Option #1: Use one reference of the PixiJS application and start/stop it when the component mounts.

import React, { useRef, useEffect } from "react";
import { Application } from "pixi.js";

const app = new Application({
  width: 800,
  height: 600,
  backgroundColor: 0x5BBA6F,
});

function MyComponent() {
  const ref = useRef(null);

  useEffect(() => {
    // On first render add app to DOM
    ref.current.appendChild(app.view);
    // Start the PixiJS app
    app.start();

    return () => {
      // On unload stop the application
      app.stop();
    };
  }, []);
 
  return <div ref={ref} />;
}

Option #2: Create a new PixiJS application each time the component mounts.

import React, { useRef, useEffect } from "react";
import { Application } from "pixi.js";

function MyComponent() {
  const ref = useRef(null);

  useEffect(() => {
    // On first render create our application
    const app = new Application({
      width: 800,
      height: 600,
      backgroundColor: 0x5BBA6F,
    });

    // Add app to DOM
    ref.current.appendChild(app.view);
    // Start the PixiJS app
    app.start();

    return () => {
      // On unload completely destroy the application and all of it's children
      app.destroy(true, true);
    };
  }, []);
 
  return <div ref={ref} />;
}

I’ve noticed some quirks where when using Option #1 some changes I make will add an additional PixiJS application to the DOM which could be solved by removing the ref’s children before appending. I will probably continue using Option #2 for now unless I find a reason not to. The biggest con to using Option #2 is the PixiJS application isn’t created until after the DOM has rendered.

Bookmark(0)

No account yet? Register

Published by Chris London

A serial entrepreneur, Chris is currently co-founder and CTO of tech start-up Cinch. Cinch is an automated marketing platform designed to share the right message at the right time with your customers.

Leave a comment

Your email address will not be published. Required fields are marked *