How to target react compunents from a map list using useRef

Viewed 33

I'm tring to make few buttons that corresponds to keyboard keys , But i'm fairly new to React and i don't know how to target those elements ,Each element have it's id and i can access the event key but after that i'm lost ,I alredy tried using refs but i didn't find an example that i can work with or understand how can i turn it to use inside my code. This is the array of objects im using to genrate a list of compunents:

   const [bankOne,setBankOne] = React.useState([
    {
      keyCode: 81,
      keyTrigger: "Q",
      id: "Heater-1",
      url: "https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3"
    },
    {
      keyCode: 87,
      keyTrigger: "W",
      id: "Heater-2",
      url: "https://s3.amazonaws.com/freecodecamp/drums/Heater-2.mp3"
   }]);

this is the event handler:

  const handleKeyPress = React.useCallback((event) => {
    //console.log(event.key.toUpperCase());
    console.log(itemsRef.current)
   }, []);

  React.useEffect(() => {
    document.addEventListener('keypress', handleKeyPress);
    return () => {
      document.removeEventListener('keypress', handleKeyPress);
    };
  }, [handleKeyPress]);

this is the list im using to genrate React compunents:

  const bank1 = bankOne.map((item,i) => (
    <button
      ref={el => itemsRef.current[i] = item.keyTrigger}
      id={item.id}
      className="drum-pad"
      value={item.keyTrigger}
      onClick={handleClick}
      onKeyPress={handleKeyPress}
    >
      <audio  src={item.url} className="clip" id={item.keyTrigger}>
        <source src={item.url} type="audio/mp3" />
      </audio>
      {item.keyTrigger}
    </button>
  ));

i have no idea how to do this ,that's why i didn't post any of the ways i tried to solve the problem because i know they were all wrong one way or another . i really appreciate any help ,and thank you all.

1 Answers

so i learned that i only needed a useRef array and then i targeted each button by it's index in that array,maybe not the best solution but at least it worked .

  const btnsRef = React.useRef([]);
    const handleKeyPress = React.useCallback((event) => {
   switch(event.key.toUpperCase()){
      case "Q":
        btnsRef.current[0].focus()
        btnsRef.current[0].firstChild.load()
        btnsRef.current[0].firstChild.play()
       setData(prev => ({...prev,currentNote: btnsRef.current[0].id}))
        break;
        case "W":
        btnsRef.current[1].focus()
        btnsRef.current[1].firstChild.load()
        btnsRef.current[1].firstChild.play()
       setData(prev => ({...prev,currentNote: btnsRef.current[1].id}))
        break;
}
   }, []);

  const component = obj.map((item,index) => (
    <button
      ref={(element) => btnsRef.current[index] = element}
      id={item.id}
      value={item.keyTrigger}
      onKeyPress={handleKeyPress}
    >
      <audio className="clip" id={item.keyTrigger}>
        <source src={item.url} type="audio/mp3" />
      </audio>
      {item.keyTrigger}
    </button>
  ));

Related