Tráta Timer

Project Purpose and Goal

When I was first learning to code, the Pomodoro tecnique was really helpful in getting me to focus and get work done. You complete a session (usually 25 minutes), then take a short break (say 5 minutes), and after you've completed a group of sessions you take a longer break.

I built the first version of this app while completing freeCodeCamp's Frontend Libraries certificate, which focuses on React. The user stories for that project included:

  • You can start, pause, and reset the timer.
  • You can change the length of the session or break.
  • An alarm sounds after each session or break.
  • The timer automatically switches to a new session or break once the current one is completed.

In addition, I added an animated progress circle using SVG to give visual feedback on how much time was left.

A few months later I rewrote it to use React hooks instead of class-based components and added new features:

  • You can choose between a session, short break and longer break.
  • After every four completed sessions, the break will be set to at least fifteen minutes.

Coming back to the project, I added the ability to toggle between Irish and English, because I wanted to learn more about internationalization (agus tá chuile rud níos fearr le Gaeilge).

Tech Stack

React, especially hooks, provided a clean way to manage app state and update the UI. Gatsby made it realtively straightforward to turn the app into a Progressive Web App using gatsby-plugin-manifest and gatsby-plugin-offline. gatsby-plugin-intl also made it possible to add support for multiple languages. SVG allowed for animations that would not be possible with CSS alone.

Problems and Thought Process

This app had to keep track of multiple changing values: session and break lengths, time left, number of completed sessions, and the type of timer currently running. The useState hook made it easier to track and update these individual pieces of app state.

Working with setInterval in React can be tricky (see Dan Abramov's Making setInterval Declarative with React Hooks). Getting the timer to work required developing a greater understaning of both setInterval and useEffect.

Animating the progress circle required me to learn some of the internals of SVG, such as stroke-dasharray and stroke-dashoffset. The next challenge was keeping the session/break length and time left in sync. I did this through a combination of state management and controling when the user can change these values so as not to break the SVG.

Lessons Learned

Rewriting the app to use functional components with hooks rather than class-based components gave me a better understanding of the differences between the two approaches to writing React components.

Making the app bilingual taught me about some of the challenges of internationalization, such as keeping content in multiple languages in sync and managing navigation between languages.

This project clarified some core JavaScript functionality around setting and clearing intervals, leaving me better prepared to use these features in future projects.

Hi, I'm Gerard Hynes. I write about JavaScript and modern web development.

You can usually find me on Twitter

Gerard Hynes © 2021