Home > Back-end >  Can't use Context Provider properly
Can't use Context Provider properly

Time:04-16

VolumeContext --

const VolumeContext = React.createContext<IVolume>({volume: 1});
export default VolumeContext;

Interface --

export interface IVolume {
  volume: number;
}

Volume --

import { useState } from "react";

const Volume = () => {
  const [volume, setVolume] = useState<number>(1);

  const setVolumeHandler = (event: React.ChangeEvent<HTMLInputElement>) =>
    setVolume(parseFloat(event.target.value));

  return (
    <div className="volume">
      <h2>Volume</h2>
      <input
        type="range"
        onChange={setVolumeHandler}
        value={volume}
        min="1"
        max="10"
        step="0.01"
      />
    </div>
  );
};

export default Volume;

App --

<VolumeContext.Provider value={{ volume: 1 }}>
          {AudioClips.map(({ keyTrigger, url }: IAudioClips) => (
            <Pad key={Math.random()} keyTrigger={keyTrigger} url={url} />
          ))}
       </VolumeContext.Provider>

Pad --

const Pad = ({ url, keyTrigger }: IAudioClips) => {
  const { volume } = useContext(VolumeContext); // Using the VolumeContext for 'volume'

const playSound = useCallback(() => {
    // To play the sound when the button is clicked
    setActive(true);
    transition();
    audioTag.current.currentTime = 0;
    audioTag.current.play();                 
    audioTag.current.volume = volume;    // In this line I'm using the **volume** context
  }, [volume]);

Playground: https://codesandbox.io/s/dazzling-night-c22krw?file=/src/App.tsx

So, there's no error but Volume isn't working. Can anyone please help?

CodePudding user response:

You should provide in your provider both volume and setVolume, and then use them inside Volume component via useContext. Your VolumeContext should look like this:

const VolumeContext = React.createContext<IVolume>({
  volume: 1,
  setVolume: () => void 0
});

Then in App component provide values:

function App() {
  const [volume, setVolume] = useState<number>(1);
  return (
    <div className="container">
      <h2>Drum Machine</h2>
      <div className="mini-container">
        <VolumeContext.Provider value={{ volume, setVolume }}>
          {AudioClips.map(({ keyTrigger, url }: IAudioClips) => (
            <Pad key={Math.random()} keyTrigger={keyTrigger} url={url} />
          ))}
          <Volume />
        </VolumeContext.Provider>
      </div>
    </div>
  );
}

In Volume component use them:

const Volume = () => {
  const { volume, setVolume } = useContext(VolumeContext);
  const setVolumeHandler = (event: React.ChangeEvent<HTMLInputElement>) =>
    setVolume(parseFloat(event.target.value));

  return (
    <div className="volume">
      <h2>Volume</h2>
      <input
        type="range"
        onChange={setVolumeHandler}
        value={volume}
        min="1"
        max="10"
        step="0.01"
      />
    </div>
  );
};

Working example you can check here https://codesandbox.io/s/quizzical-chatterjee-ynz568?file=/src/components/Pad.tsx

CodePudding user response:

Set volume value range between [0-1] here

audioTag.current.volume = volume; 
  • Related