Templates
TypeScript
React-ECS

React-ECS

This template is for developers who use React (opens in a new tab).

You can start a new project using this template with:

pnpm create mud tutorial --template react-ecs

For more information, see the quickstart guide.

Onchain code

This template uses the standard Counter onchain code.

Offchain code

The files you are likely to need to change in the offchain code are:

App.tsx

export const App = () => {
  const {
    components: { Counter },
    systemCalls: { increment },
  } = useMUD();

Get the MUD API information.

const counter = useComponentValue(Counter, singletonEntity);

This is the way you specify a listener for a MUD table in React. Every time the value in the table changes, the listener causes the React component in which it is registered (in this case, App) to be rendered again with the new information.

  return (
    <>
      <div>
        Counter: <span>{counter?.value ?? "??"}</span>
      </div>

This is the way you use a MUD component's value in React. counter?.value means that there may or may not be a value in the counter, and if there is return it. counter?.value ?? "??" means that if there is no value the result of the expression is "??".

      <button
        type="button"
        onClick={async (event) => {
          event.preventDefault();
          console.log("new counter value:", await increment());
        }}
      >
        Increment
      </button>
    </>
  );
};

The call we use for the onchain system is returned by useMUD(). Here we use it when the button is clicked.

createSystemCalls.ts

This file is where you place the calls that go to the onchain system. In this case there is only one, increment.

const increment = async () => {
  /*
   * Because IncrementSystem
   * (https://mud.dev/tutorials/walkthrough/minimal-onchain#incrementsystemsol)
   * is in the root namespace, `.increment` can be called directly
   * on the World contract.
   */
  const tx = await worldContract.write.increment();
  await waitForTransaction(tx);
  return getComponentValue(Counter, singletonEntity);
};

You create a transaction, wait for it to be included, and return the value. If there is any need for translation between the parameters provided by the user interface and those that are expected by the onchain code, this is where you would add it.