I have embedded a Phaser 3 game inside a page with React components.
I was wondering if it was possible to have the game to interact with components.
For example, if a player makes a specific move in game, a component state is updated with the move’s data.
I am new to React, I’m afraid methods like setState() cannot be called from an external code.
Does someone know if it is possible in some way ? Thanks !
Definitely possible. You’re right that methods like setState cannot be called from an external node.
A few ideas off the top of my head:
If you are using a flux implementation in your React project, you can probably call an Action from within the phaser game’s code.
You could use a React Hook (see here and here and here and here) and make it available to your game’s code. React Hooks basically make it possible to call setState from an external node.
So, I read about the React hooks and the way it allows to update the state of a component looks like a good solution. But this restriction might be a problem :
Only call Hooks from React function components . Don’t call Hooks from regular JavaScript functions. (There is just one other valid place to call Hooks — your own custom Hooks
So I guess I have to use customs hooks. @snowbillr when you say making the hook available from my game’s code, do you mean creating the hook inside of it ?
I tried to make a simple hook to test. I made a component function displaying a counter. I wanted to set its value to 5 and to be re-rendered anytime the mouse moves, but I’m struggling to make it work.
I’m not sure about what problems the restriction will cause, but I can talk a little bit more about the React question.
(Disclaimer, I haven’t used Hooks, only read about them.)
I think your issue is coming from the fact that you are adding the event handler in the useEffect function. Could you try setting up the event handler just in the useCounter method rather than in a useEffect block?
Since React does some cleanup with that returned function from the useEffect block, I’m wondering if that’s causing issues in-between renders.
As far as making the hook available to your game’s code, I was thinking you could export it somehow from a js file and import that into your game. If that’s not possible though, you’ll have to do this another way. Sorry that’s not super helpful
I am currently making the phaser + react hybrid project. The glue for this is a MobX library.
I have data classes with the properties exposed as MobX @observable. That data mapped directly into the React components. Game engine modifies that data with MobX @action decorated functions.
Then there is a magic between MobX and React so React is always updated with the MobX state.
I suppose you should play with the MobX+ React itself and then put the Phaser into when you become familiar with the concept.
Example queue updating the ingame money in react component:
UI or internal event in phaser ->
manual call: @action ()=>{Data.money ++}
(setting up): @observable money in Data Class
…autoupdate by MobX -> React component <button text={Data.money}></button>
Just adding my 2 cents since I’m also working on a project using both React and Phaser 3.
The way we linked both is quite simple, we simply used EventEmitters.
When something interesting happens in Phaser, we emit an event and our React components are listening to them. We can then use setState since we’re back inside React.
It also perfectly work the other way around when we need to update Phaser based on React events.
I’ve had a lot of success using react components as menus on top of a canvas that runs a webgl instance. You can make the menus children of the overall game instance and have them pass data back and forth.
@jdnichollsc Hi, I feel dumb, but I don’t understand how to pass props so that Phaser uses them, maybe you know a little example to understand the principle.
wondering if there are good examples out there to work off on integration?
i found react-phaser-hooks but it hasn’t been updated in two years since react 16 (now at 18)
there’s also a CreateReactApp template phaser3-project-template but that also seems to rely on outdated methods
Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. . Learn more: https://reactjs.org/link/switch-to-createroot
it’s also using Class components where I would prefer functional and hooks.
other suggestions / examples appreciated of how to get things working in 2022!