Lessons Learned from my First Four React Projects

Over the past few weeks, I have been working through the freeCodeCamp Front End Libraries certificate as I learn React. I’ve been doing web development in some capacity for at least the past four years, but recently I’ve aimed to step up my game and add new skills mostly surrounding JavaScript.

That being said, I by no means am new to web development, so I will put almost zero focus on the design or styling of these apps. Almost all of my takeaways are things that I learned for the first time either within React or just cool JavaScript tricks that I’ve never found myself using before.

In the past few weeks, I have built the following applications in React: a Markdown previewer, a drum kit, a four function calculator, and a Pomodoro clock.

Here are my takeaways from each project:

Markdown Previewer

With this being my first project built in React, almost everything seemed foreign. I understood that React was based on components, but I did not grasp how state and props were really passed between different components.

I started this project by actually writing out the elements in HTML like I usually start a project and thought I would then just render the components into each HTML element with ReactDOM.

I quickly learned this would not work if I wanted all of them to interact (which was the whole point of this simple project).

Thus, in order for the main two components to communicate with each other, they had to have a shared parent element, which I simply called App. Then I could manage state in the App component and pass the given props to the Editor and Viewer components. Then the App component was the only one rendered to a single HTML element.

While I had to use the Marked.js library for the first time in this project, the main thing I took away from my Markdown previewer was how to set up the basic structure of a simple React app which I would use in the next three projects.

This project, and the rest of my projects, had this basic code structure:

HTML:
<div id='main'></div>
JavaScript:
class App extends React.Component {
constructor(props) {
super(props);
this.state = { example: 'example' }
}
render() {
return (
<div id='app'>
<Editor />
<Viewer />
</div>
);
}
}
class Editor extends React.Component {}
class Viewer extends React.Component {}
ReactDOM.render(<App />, document.getElementById('main'));

Drum Kit

With my drum kit project, I probably learned more about simple JavaScript uses than I did about React. For the drum kit, I had to use HTML5 <audio> elements for the first time as well as learn how to play audio files at the right time stamp with sound.currentTime = 0 and sound.play().

However, with the help of React, I learned how easy it is to make one component, in this case a single drum pad, and then easily duplicate it several times so that the same methods and functionality are used for each one. With the help of the map() function, I was then able to render each of the nine drum pads with their respective sounds. This portion of the code looked like this:

let soundBank = [
// An array of objects that held my sound names and src's
];
let sounds = soundBank.map((drumObj, i, soundBankArr) => {
return (
<Drum keyCode={soundBankArr[i].keyCode}
drumType={soundBankArr[i].drumType}
keyLetter={soundBankArr[i].keyLetter}
url={soundBankArr[i].url}
updateDisplay={this.props.updateDisplay} />
);
});

While I could have probably made a drum kit with plain JavaScript, this was one of the first time’s I really appreciated what React had added and how easy it was to make actual applications and not just a collection of functions on a website.

Four Function Calculator

I like how freeCodeCamp ordered their projects for this certificate as each one built on the one before it. I was able to get through the first three projects of the certificate, including the first two with React without too many issues.

Then I got to the calculator. With the calculator I learned quickly that state really needed to be controlled at the top level component because any information that was needed at sibling components or parent components could only be passed down through props and not back up through state or any other means.

Once I realized that almost all of the control had to be in the top level Calculator component, the rest came down to all of the edge cases that the freeCodeCamp specifications requested be handled in particular ways.

For this project, I spent the most time debugging out of my first four React projects. With the calculator, I messed around a lot trying to figure out the best way to store previous answers so that they could then be referenced in other operations immediately following the previous calculation.

I ended up having to store value to be displayed and the actual answer (while at some points they are the same) in two different state properties. This way I could use the last answer by default if an operator was immediately pressed without having to change the view too early.

Although I’ve since done some reading about the wrong use cases for the eval() function in JavaScript, it was the perfect thing in this application and saved me plenty of time. I thought I was going to have to parse my formula string manually and make my calculator function more like an adding machine. Instead, I just passed my formula string into eval() and it would output the answer.

This looked like this for a given set of inputs:

let finalFormula = this.state.displayFormula;
let answer = eval(finalFormula);
// I then rounded my answer to 6 decimal places but trimmed unnecessary zeros
answer = +answer.toFixed(6);

I was really starting to feel like I was getting the hang of React and was proud of what I had built up to this point, but one project remained and it turned out to be the one that really showed me how much I still didn’t fully understand.

Pomodoro Clock

While totally unrelated to React the first thing I learned during this project was what the Pomodoro technique actually is. Basically it’s a productivity method where a user focuses on a task for a given time (25 minutes) and then takes a break (5 minutes) before just repeating the process until the task is done or it’s time to stop working.

Remember when I wrote that I had learned how important it was that React only passes information down to child components and information doesn’t really flow back up? Well, apparently I still didn’t fully understand that because it ended up being my biggest tripping point for my Pomodoro clock application.

I quickly implemented the components that incremented and decremented both the break and session lengths and even easily updated the corresponding timer.

However, when I went to start making the timer actually tick, nothing seemed to work like I expected it to. I spent a good two days trying to make my stubborn first attempt work but eventually had to accept that I just wasn’t doing it the best way and had to eventually scrap my thinking and essentially start over.

From there I moved almost all of my state properties that were in my Timer component back up the the App component that was controlling everything. It was then that I was able to actually updated the timer and both of the settings components and actually see evidence that they were all talking to each other.

Finally, I was able to actually address the function of counting down the timer which I thought was much harder than it needed to be.

With my realization of the correct React approach out of the way, I then managed to implement the countdown with a simple setInterval() method that was basically just this:

let id = setInterval(() => {
if (this.state.status === 'running') {
if (this.state.time > 0) {
this.setState({ time: this.state.time - 1 });
} else if (this.state.time === 0) {
this.playSound(); // Plays the buzzer sound
if (this.state.mode === 'session') {
this.setState({
mode: 'break',
time: this.state.breakLength * 60
});
} else {
this.setState({
mode: 'session',
time: this.state.sessionLength * 60
});
}
}
}
}, 1000);

this.setState({ intervalId: id });

This code may look complicated but it’s basically just doing the following every second:

  1. Check if the clock still has a status of ‘running.’
  2. Check if the time remaining is greater than zero.
  3. Decrement the timer by 1 second.
  4. If the timer hits zero, play a sound, and switch the mode from ‘session’ to ‘break’ (or the other way around).

While this was the more involved portion of the code, there was also a separate portion that stopped the timer. To do this, I had a state property for the status of the clock (‘running’ or ‘stopped’) and then the start/stop button would simply toggle this status.

My first solution just had the setInterval() function being called which resulted in it resuming as soon as the start button was pressed again along with a new setInterval() being called.

To fix this issue, I captured the intervalId that is returned by the setInterval() function and then stored that id in the state so that when the stop button (or reset button) is pressed, the previous setInterval() is canceled.


Those are the four projects that I completed using React to attain my ‘Front End Libraries’ certificate from freeCodeCamp. I wanted to write about these projects shortly after completing them so that I could come back later and reflect on what I learned, but I also hope others that are just starting to learn React (or maybe those that have already learned React) could maybe get a few tidbits from my experiences.

You can find each of these working projects (and other things I’ve made) along with the source code for each one on my CodePen profile.

If you have comments or questions about either of my projects, or if you would like to follow along with my current #100DaysOfCode challenge, I’d love to interact on Twitter!

Thank you for taking the time to read through this overview of my first four React projects and I hope you enjoyed the insight or at least learned one interesting thing.