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:
packages/client/src/App.tsx
(opens in a new tab), which controls the information displayed to the user. It is the place where you register handlers that are called when the value in a component (basically, a table) changes.packages/client/src/mud/createSystemCalls.ts
(opens in a new tab), which is where you write code that performs calls to an onchain system.
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.