Tutorial

Adding Sound FX to Your React Apps

Published on May 21, 2019
author

William Le

Adding Sound FX to Your React Apps

In this article, learn how to incorporate sound effects in your React apps using a small library called uifx.

Sound effects aren’t used often for apps. You usually just see them on Big Tech’s apps like:

  • The iOS keyboard makes a wooden tap sound
  • Twitter iOS app makes a “boop” noise when you pull-to-refresh
  • “Hey Google” and “Hey Siri” have distinctive memed tones when you invoke their names

I think we’ve grown so accustomed to these “noises” that they’re not even considered interesting features anymore. But they are! Imagine if Apple suddenly decided to remove the “tick-tack” sound from their keyboard. For those of us who’ve gotten used to that familiar noise, we’d probably feel some kind of strange aural deprivation. Yet for web apps, we almost never see sound effects (sfx) built into the user interface and frankly… we almost don’t expect them to be there.

iOS/Android apps aren’t the only digital mediums that can express themselves with sounds. The web can… and should embrace sound effects more!

Introducing UIfx

I realized there were a lot of full-fledged audio libraries like SoundManager or Howler, but none of them were designed for UI sound effects which require a fire-and-forget strategy for playing mini-sound bites… so I built a simple library for this called uifx:

import UIfx from 'uifx';
import mp3File from './my-sounds/beep.mp3';

const beep = new UIFx({asset: mp3File});

<button onClick={beep.play}>Signup</button>

React is used here but you can use it in any JavaScript environment that has the Audio API –– which is most modern browsers!

Basic Usage

Here’s a practical example where sound fx is used to provide audio feedback on an <input type="range"/> element.

import React, { Component } from 'react';
import UIfx from 'uifx'; 
import tickAudio from './my-sounds/tick.mp3';

const tick = new UIfx({asset: tickAudio});

export default class InputRange extends Component {
  state = {
    value: 0,
  }
  onChange = (event) => {
    this.setState({ value: event.target.value });
    tick.play();
  }
  render() {
    return (
      <div>
        <div>{this.state.value}</div>
        <input
          type="range"
          value={this.state.value}
          onChange={this.onChange}
        />
      </div>
    )
  }
}

Don’t you get a mental picture of a watchmaker’s tool or something? How interesting is that?! Audio adds a completely new sensory experience!

Throttling Playback

UIfx is designed specifically for playing tiny audio files in rapid succession. Sometimes, however, you’ll want to throttle playback a bit so it doesn’t sound too crazy or overload the user’s speakers:

const tick = new UIfx({
  asset: tickAudio,
  throttleMs: 40
})

Finding the right balance of realtime feedback is more an art rather than a science. I usually try to put myself in user’s shoes and ask myself how much instant audio feedback I would want, and throttle accordingly.

Changing playback volume

By default, sounds will play at full volume. To change the volume of a UIfx sound, call UIfx.setVolume() method:

beep.setVolume(0.8).play();

// or...

beep.setVolume(0.8);
beep.play();

Valid arguments are 0.01.0 to emulate the Audio api. In the demo below the volume is changed using the previous <input type="range"> slider:

class ToastNotifications extends Component {
  state = {
    isToastVisible: false,
    volume: 0.5,
  }
  sfx = {
    beep: new UIfx({asset: beepAudio}),
    tick: new UIfx({asset: tickAudio, throttleMs: 100}),
    appear: new UIfx({asset: appearAudio}),
    disappear: new UIfx({asset: disappearAudio})
  }
  onVolumeChange = (event) => {
    this.setState(
      { volume: event.target.value },
      // "setState" cb to get updated volume 👇
      () => this.sfx.tick.setVolume(this.state.volume).play()
    )
  }
  toggleToast = () => {
    this.setState(
      { isToastVisible: !this.state.isToastVisible },
      () => {
        this.state.isToastVisible  // 👈 decide which sfx to play
          ? this.sfx.appear.setVolume(this.state.volume).play()   
          : this.sfx.disappear.setVolume(this.state.volume).play()
      }
    )
  }
  render() {
    return (
      <div>

        <button onClick={this.toggleToast}>
          Toggle notification
        </button>

        <div>
          Volume: {this.state.volume}
        </div>
        <input
          value={this.state.volume}
          onChange={this.onVolumeChange}
          min="0.0"
          max="1.0"
          step="0.01"
          type="range"
        />

        <Toast isVisible={this.state.isToastVisible}/>

      </div>
    )
  }
}

If you don’t want to persist volume changes, you can easily play at a different volume by passing an argument to UIfx.play():

const tick = new UIfx({
  asset: tickMp3,
  volume: 1.0
});

tick.play(0.25); // plays at 0.25 volume
tick.play(); // plays at 1.0 volume

Conclusion

Sound effects in web apps is a relatively unexplored domain. My hope is that uifx will help you build apps that engage people more fully –– both visual and aural. Small touches like this can touch people’s hearts and provide more richer exeriences to your users.

📦 Check out [uifx](https://github.com/wle8300/uifx)! I’d love to know what you think!

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
William Le

author

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
1 Comments


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Hi William, I found your article very useful, and I’m about to go use your teachings in my project. Thank you. -Duncan Haywood

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.