An entity-component-system for React

React ECS

A declarative Entity Component System for React.

An ECS, or Entity Component System is a design pattern popular in simulations, visualizations and game-development. It eschews rich objects and complex inheritence hierarchies.

An ECS, or Entity Component System is a design pattern popular in simulations, visualizations and game-development. It eschews rich objects and complex inheritence hierarchies.

Instead:

  • Entities: A simple bag of facets.
  • Facets: Simple data-only objects.
  • Queries: Track entities which have specific facets.
  • Systems: Process the facets of entities matched by queries.

React ECS helps you build your simulations and games using this pattern, in standard React JS fashion (hooks, components, etc)

What does it look like?

Let's make a simple simulation that updates a cube based on a Spinning facet, using React ECS' ThreeJS integration @react-ecs/three.  

First define a Facet

This facet just tracks how much its entity should spin.

class Spin extends Facet<Spin> {
    amount? = new Vector3(1, 1, 1);
}

Then define a System

Systems use queries to track the entities they work upon.

This system uses a query to find entities with both the ThreeView and Spin facets. ThreeView is facet provided by @react-ecs/three to visually display entities in a ThreeJS scene.

This system updates the entity's 3D rotation based on the Spin facet:

const SpinSystem = () => {
    const query = useQuery((e) => e.hasAll(ThreeView, Spin));

    return useSystem((dt) => {
        query.loop([ThreeView, Spin], (e, [view, spin]) => {
            const rot = view.object3d.rotation;
            rot.x += spin.amount.x * dt;
            rot.y += spin.amount.y * dt;
            rot.z += spin.amount.z * dt;
        });
    });
};

Now put it all together

Now we can create a component to tie it all together. For more information see our documentation and examples.

export const SpinningCubeStory: FC = () => {
const CoolSim = () => {
  const ECS = useECS()
  useAnimationFrame(ECS.update)

  return (
    <Canvas>
      <ECS.Provider>
        <SpinSystem />
        <Entity>
          <Spin />
          <ThreeView>
            <Box />
          </ThreeView>
        </Entity>
      </ECS.Provider>
    </Canvas>
  )
}