loading...

How I Built a Drum Machine in React, Part One: Basic Architecture and Style

dylanesque profile image Michael Caveney Updated on ・4 min read

March 19th, 2019

Note: This article contains a partial potential solution for the freeCodeCamp Drum Machine project, so please avoid this for now if you're actively working on that project and don't wish to be spoiled!

Background: I've completed the first two freeCodeCamp certifications, and I went off on a tangent getting deep into React while working on the Front End Libraries certification material. I thought at some point that the material was too simplistic to be interesting, but I didn't count on two things:

  • With Hooks having just become an official part of React, it's the perfect opportunity to experiment with them on smaller projects.

  • The fact that I haven't finished the certifications, particularly the Data Visualization certificate is bugging me, and I want the practice, completed projects, and bragging rights that come with finishing these.

Additionally, detailing my work process will be helpful to me (and you, I hope!), so I'm picking up where I left off with the Drum Machine project.

One note: I believe strongly in the power of creative limitations, so I'm going to limit myself in this project by NOT employing hooks. They will almost certainly simplify things, and I want experience solving problems without them, since there are many codebases out there that don't employ them.

Step One, Creating The Basic Project Structure: First, I spin up a new project with create-react-app, and delete the boilerplate code that isn't relevant to this project. Next, I take heed of the "business requirements" of the project and add layout code dictated by the user stories in the project requirements. FCC REALLY seems to like ids. I wish they wouldn't, but that's just my opinion, and they're not really getting in the way of anything.

Step Two, Defining Component Architecture: When I look at the project requirements and the sample app, two things jump out to me as obvious candidates for a component: the display, and the drum pad buttons. Jumping ahead to how data is going to flow through the app, this is what it's going to look like:

  1. App loads, and the display component shows a default message that is stored in state.

  2. When a drum pad button is pressed, a function will call a setState() to update the display with the name of the pressed button.

The basic code so far, starting with the display component:

import React from 'react';

 const Display = ({ display }) => {
  return ( <h3 id="display">{display}</h3> );
}

export default Display;

A note about destructuring: This is about as small as a component will get, so I'm not really saving any space by destructuring the props here. But I feel that it's a good habit to get into, since I will be working with components that have more props in the future, and I want this pattern to be second nature.
The Button component is essentially the same as the Display, so I won't delve into that here. By now, the App component looks something like this:

import React, { Component } from "react";

import "./App.css";
import Display from "./Display";
import Button from "./Button";

const data = ["Q", "W", "E", "A", "S", "D", "Z", "X", "C"];

class App extends Component {
  state = {
    display: "Press a key to play the drums!"
  };

  render() {
    return (
      <div id="drum-machine">
        <Display display={this.state.display} />
        <div className="drum-buttons">
          {data.map(button => (
            <Button name={button} key={button} />
          ))}
        </div>
      </div>
    );
  }
}

export default App;

So we have here....

  • Imports! My personal style is to leave an empty line between core dependencies and third-party dependencies, and between third-party dependencies and local imports. I picked up this pattern from my not-so-brief, frustrating time with Angular, and I think this makes this section breathe more and improves readability of code.

  • An array containing the button names, to be mapped over later in the component.

  • The class declaration, with initial state for the display set up. Here we have the child components being fed their respective props from the App component, and the dynamic generation of the buttons from mapping over the data array and feeding in the name. Lists in React need unique keys, and the button names here will suffice since I can guarantee that they will remain unique.

Style: I'm not going to do more that make these apps vaguely pleasant to look at for now, as I want to concentrate on the core skills of these challenges. I can always go back and enhance them later on, right? I initially had Flexbox as the layout, but I switched to Grid since that makes the specific button layout much easier.

Next time, I wire up the flow of state upon the requisite events being fired, test that, and hopefully get the MVP working!

Posted on Mar 21 '19 by:

dylanesque profile

Michael Caveney

@dylanesque

I am a largely self-taught dev from the greater Boston area. The technologies I'm most excited to work with these days are React, Gatsby, and Apollo.

Discussion

markdown guide