PixiJS v4.5 Application in a React ComponentMay 31, 2017
I recently started a new project that uses both React and PixiJS. I had some trouble setting things up at the beginning, and had to do some searches on Google about how to correctly use a PixiJS renderer in a React Component.
While doing so, I discovered some inventive libraries like react-pixi that allows a PixiJS renderer to be controlled by React directly. It would probably be a good idea to use that lib, but I wanted to implement my own logic for handling PixiJS’ renderer. I had some troubles trying to set things up in the “classic” and recommended PixiJS way. Other solutions I found are no longer working in the recent versions of PixiJS.
As no resource seemed to provide a simple explanation on how to correctly use PixiJS in a React Component now, I thought this post might be useful to some.
Before going further, here is a list of which techs I’m using for this. I of course can’t guarantee that this will work with different technologies or even different versions :
- PixiJS 4.5.1
- React 15.4.2
- Typescript 2.1.0
With this I’m also using other libs like Flux or React-Router but they’re not relevant as this post focuses purely on getting a PixiJS renderer to work in a React Component, not the general architecture of the Application.
The classic PixiJS way
On the examples visible on the website, the main class used to instantiate and control the renderer is to use PIXI.Application. The example code that uses
PIXI.Application is as follows :
By trying to mimic this when implementing a Component, we would run into an issue. We’re trying to add an element to the DOM tree directly, which isn’t what React recommends (and we’d need
A type-checked React-like way
There’s no magic trick here, we’ll still need to add the view “manually” to control it. But instead of referencing the DOM tree, we can use a feature from React called Refs to do things right. Here’s what the documentation tells us :
React supports a special attribute that you can attach to any component. The
refattribute takes a callback function, and the callback will be executed immediately after the component is mounted or unmounted.
We’ll use that to our advantage here and create a
<div> that contains a
ref attribute. We’ll then be able to interact with it by using that reference instead of trying to access the DOM.
Instead of trying to explain much longer, here’s the code in TSX of the Component whose goal is to manage and display an instance of a
Note that even though we’re calling
appendChild ourselves, we still didn’t even use
ReactDOM here. Everything is self-contained and correctly type-checked.
As the component mounts, the
ref attribute immediately calls our anonymous function which sets the
gameCanvas to that element. The
componentDidMount() function will then fire and reference it directly to add the
Pixi.Application view (which is a Pixi.SystemRenderer).
You now have all possibility to control the Application and Renderer however you like. Want the state of the Game to persist when the Component mounts/unmounts ? Just save the main
componentWillUnmount and add it back in
I use that method in my own code and it works like a charm. Even though using
ReactDOM and an
id attribute would be possible, this is prone to errors. I like to keep things organized and I think the more things the compiler is able to check, the better. It also feels less like a hack and more like a reusable and self-contained Component.