[SOLVED] Object Oriented state management in React?

Issue

I’ve been building a chess-style board game for a university project, using React for the frontend to let users interact with the game, but I’ve now run into a bit of an issue when trying to implement an AI opponent to play against.

I wanted to essentially run another copy of the game headlessly alongside the "real" game such that the AI can simulate the outcomes of different moves and determine the best one to pick. My approach to this was to replace the React state with a Game class that contains all of the attributes and methods needed to play the game; that way, there can be multiple games at once and the AI can mirror the main game, simulating the moves without affecting what’s rendered to the screen.

However, in doing so I’ve completely decoupled the game state from React’s state system so it no longer knows when to rerender on data changes and my game is now unplayable.

Is there a best practice for what I’m trying to do, or can anyone see how I might be able to fix this?

Happy to provide any more information or code snippets if it’s helpful!

Solution

I’d suggest you check MobX out

Anything that can be derived from the application state, should be. Automatically.

Simple enough, you can use it for your Game class to create instances

I don’t know how your Game class look like but you can take this as an example

import React from "react"
import ReactDOM from "react-dom"
import { makeAutoObservable } from "mobx"

class Game {
    isStarted := false

    constructor() {
        makeAutoObservable(this) //need this for MobX when you create a new instance
    }

    start() {
        isStarted = true
    }
}

Here is how we integrate it with your component

import { observer } from "mobx-react-lite"

export const GameView = observer(({ game }) => (<>
   <span>{game.isStarted}</span>
   <button onClick={game.start}>Start game</button>
</>))

export default GameView

The upper component can be like this

const App = () => {
   const game = new Game()
   return <GameView game={game}/>
}

Answered By – Nick Vu

Answer Checked By – Pedro (BugsFixing Volunteer)

Leave a Reply

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