I created this Podcasts web app as an excuse to build something with React. And a single-page app architecture makes sense for a podcast app, to allow media to play as you browse.
Managing the app state with reducers
The app uses React Router v6 for navigation, which has a new React Hooks-based API which is really nice to work with. I used React’s in-built reducers (
useReducer) along with the Context API to manage the app state. React’s reducers work similarly to Redux, but are guaranteed to have forward compatibility with the upcoming Suspense API and Concurrent Mode. Dan Abramov’s two egghead.io courses on Redux are an excellent resource for learning how reducers work.
Parsing RSS feeds with Netlify functions
Syncing the audio element with the app state
One of the trickiest parts was working around the “impedance mismatch” between the React programming model and the browser’s native audio element. I initially wanted to have the audio element be driven by the app state, however, the element can also be controlled by the browser. Media playback can be controlled with function keys on keyboards or though phone lock screens and notifications. A better approach turned out to be to let the audio element take care of its own state, and use event listeners to keep the app state up to date. To do this, I had to be able to call the
pause() methods on the audio element from anywhere in the app. I made the audio element available globally using
useRef with the Context API.