A ETH Dapp boilerplate project using Reactjs and Drizzle

Hao Tang
5 min readDec 7, 2018

--

Truffle is great, it simplifies contract development, testing and deployment to Ganache (local), testnet and mainnet if needed. There are many excellent tutorial articles that explains how to use Truffle to code a contract out there. I’ve learned a lot following them. After attending Trufflecon 2018, I decided to give Drizzle a try. However, I felt a bit lost trying to follow the tutorials and documentation around Drizzle. I coded this boilerplate project. This article tries to explain what’s in the project and how it works together.

If you just want to jump in and see the code, you can checkout the code on Github.

For the first couple steps such as: setting up development environment, creating a truffle project, writing the smart contract, compiling and migrating the smart contract and testing the smart contract, I found this official tutorial by Truffle very helpful. From step 8 “Wire up the React app with Drizzle” is where we diverge from the official tutorial.

Here are the steps from the official tutorial just for reference:

Setting up the development environment

Creating a Truffle project from scratch

Writing the smart contract

Compiling and migrating the smart contract

Testing the smart contract

Creating our React.js project

Setting up the front-end client

Wire up the React app with Drizzle

Write a component to read from Drizzle

Write a component to write to the smart contract

First, complete the steps till step 7: Setting up the front-end client. The truffle part boilerplate code is pretty much the same. Except that, in my example, I used the SimpleStorage contract that stores a uint variable.

Now, go to the client directory, it is where things get interesting. Beside drizzle, I also have drizzle-react, material-ui, react-router, redux and redux-router installed. Don’t worry if you are not an expert on every package. Neither am I. As we go through the code, it will become clearer how things work together.

Wire up the React app with Drizzle

Here we use DrizzleProvider from drizzle-react instead of passing drizzle as a prop to App component. It’s the same method as described in Truffle’s official getting started guide. However, I’m using it slightly differently from Truffle’s guide. The index.js code snippet is as follows. I’ll explain the differences below.

For index.js, I chose to have the router is in the App component. Thus, you don’t see it here. The rest of the code above is more or less self-explanatory. Redux DevTools composeEnhancers is added to allow neat features of Redux DevTools such as time travel to work.

Write a component to read from Drizzle

This part is quite different from Truffle’s tutorial. When I was researching this topic, I couldn’t find any similar documentation on Truffle’s site or anywhere else online.

There are two files needed to accomplish this task. App.js, obviously, will be the entry point of the rest of the components. Home.js will be displaying the value read from Drizzle.

Here is the relevant part of App.js:

For App.js, we can start with render() function. Here, I wrap <Router> outside <div className=”App”> and have <Route> inside <main> to accomplish the necessary routing work. I want to have a <AppBar> from material-ui on top that has the buttons to different routes.

I want the default route or “/” to point to Home component and show the value read from Drizzle.

You can ignore the <Snackbar /> part for now. I’ll explain this part later.

Here is the relevant part that explains how to use Drizzle to read from contract:

I didn’t find drizzle-react-component very useful. I’m not sure whether it’s because there isn’t much documentation and sample code around or because the use case is too specific / narrow for someone writing a react web application. As a result, I’m not using <LoadingContainer> either.

For Home.js, here we dispatch “GET_STORED_VALUE” action to have a Saga worker read from the contract.

The rest of the code should be self explanatory. Otherwise, feel free to leave a comment below or contact me.

Here is relevant saga code that reads the stored value from blockchain:

getStoredValueWatcher watches for “GET_STORED_VALUE” action. Once it gets the action, it dispatches “GETTING_STORED_VALUE” action and the UI will display “loading…” instead of the stored value. It will start the polling worker pollSagaWorker() function. The polling worker then checks the stored value every 200ms until it gets the stored value.

Write a component to write to the smart contract

Edit.js has the component that write to the smart contract. Here is relevant code:

There are a number of things added from Drizzle’s documentation and Drizzle box. For now, the most important line is where cacheSend() is called. You can also use send() as shown in Drizzle’s documentation.

How Redux and Saga works together with Drizzle

Drizzle uses Redux and Saga internally. We can take advantage of that and have Drizzle do some amazing work for us. Before diving into the rest of the details above, let’s take a look at saga and reducer code first.

Here I take a couple actions from Drizzle’s store. ‘PUSH_TO_TXSTACK’ is used to show <Dialog /> on Edit..js. This action is dispatched after user clicks the Set button on the page.

‘TX_ERROR’ is dispatched when user clicks the reject button in MetaMask window. Here I want to show a <Snackbar /> on the page to notify the user that she / he rejected the transaction.

‘’TX_BROADCASTED’ is dispatched when user clicks the confirm button in MetaMask window. There are two things I’d like to do after user clicks confirm and sends the transaction to Ethereum. Firstly, I’d like to redirect to ‘/’ route. Then, I’d like to pop a <Snackbar /> letting user know that the (d)Dpp is checking the transaction and waiting for the transaction to confirm on chain.

Once ‘TX_SUCCESSFUL’ is received, I’d like to refresh the UI to show the new value that’s stored on chain now.

Now, onto the reducers.js

dappReducer is responsible for changing the global state of the (d)App as the actions being dispatched. The UI will behave according to the state changes.

It will open a dialog like the following after user clicks the SET button.

This is possible because saga takes the action ‘PUSH_TO_TXSTACK’ which is dispatched by Drizzle once we call cacheSend() function and bring up the Metamask window.

If you click the REJECT button, it will show a <Snackbar /> letting you know that you’ve rejected the transaction. It’s done through saga taking the action ‘TX_ERROR’.

If you click the SUBMIT button, it will first go back to the home route (‘/’ route) then a <Snackbar /> will be displayed on the home route. Once we receive ‘TX_SUCCESSFUL’ the <Snackbar /> will close and stored data will be updated according to the value you put in the edit route.

Besides the client side dapp code, I also made some change to the test code compared to the drizzle box.

The same reason that I prefer async / await to Promise.

For future improvement of this boilerplate project, I’ll make some changes to how context is consumed because it’s currently using the old react context API. Once this PR gets merged, I’ll be able to update to the recommended context API.

I hope this boilerplate helps in your dapp development using Truffle and Drizzle. Leave a comment below or contact me on Twitter if you have any questions or comments.

--

--