reactjshowler.js

HowlerJS in React


Does anyone have experience with Howler in Ract? I have a simple function (handleRave), which should turn music on and off via useState. It works, however I can't stop "Rave" after turning it on.

I'm really stuck here.

import Rave from "../assets/audio/Rave2.mp3"
import {Howl, Howler} from 'howler';

function Header() {

    const [musicOn, setMusicOn] = useState(false);

    const sound = new Howl({
        src: [Rave]
    });

    const handleRave = () => {
        Howler.volume(0.8);
        if(musicOn === false){
            setMusicOn(true);
            sound.play();
            console.log("start")
        }
        if(musicOn === true) {
            setMusicOn(false);
            sound.stop();
            console.log("stop")
        }
    }

    return (
        <section className="header">
            <nav className="header__nav wrapper">
                {
                 musicOn === false
                ? 
                 <button style={{padding: "10px"}} onClick={() => handleRave()}>Click to begin!</button>
                : 
                 <button style={{padding: "10px"}} onClick={() => handleRave()}>Stop raving</button>    
                }
                


Solution

  • Create the sound only once, when the component is mounted, not on every render:

    const sound = useRef(new Howl({
        src: [Rave]
    }));
    

    then use

    sound.current.play();
    

    and

    sound.current.stop();
    

    Your current implementation is creating and referring to a new sound every time, so one which was previously .played won't be the same one that gets .stopped.

    Another implementation that only calls new Howl once would be to use state instead:

    const [sound, setSound] = useState();
    useLayoutEffect(() => {
      setSound(new Howl({ src: [Rave] }));
    }, []);