'How do I make each button drop show the video that is clicked? ReactJS

I am passing through props to my Buttons.jsx file. Each button would drop down a video. My problem is that when I click one button, all of the videos appear. I want it so that only that certain video that was clicked would show.

here is the link to repo

https://noahfarinas.github.io/stretching/

Thanks in advance!

Buttons.jsx

import { useState } from "react";
import ReactPlayer from "react-player";

export const Buttons = (props) => {
  const { content } = props;
    const [showVideo,setShowVideo] = useState(false);
    
    const handleOnClick = () =>  setShowVideo(true); 

   

  return (
    <div className="buttonContainer">
      {content.map((item) => (
        <div className="buttonSpace">
        
            <button id="btn" onClick={handleOnClick}>{item.title}</button>
            {showVideo ? <ReactPlayer url={item.embed} /> : null}    
         
        </div>
      ))}
    </div>
  );
};

export default Buttons;



**App.js**


import "./App.css";
import Search from "./Search";
import TitleView from "./TitleView";
import Buttons from "./Buttons";

function App() {
  const TITLE = "Stretches";

  const DATA = [
    {
      area: "upper-back",
      video: "https://www.youtube.com/watch?v=bTn89EBKJdM",
    },

    {
      area: "mid-back",
      video: "https://www.youtube.com/watch?v=VnDuWC40egg",
    },

    {
      area: "lower-back",
      video: "https://www.youtube.com/watch?v=N-xqKx8oshs",
    },

    {
      area: "hips",
      video: "https://www.youtube.com/watch?v=nLuvQCTPrcY",
    },

    {
      area: "calves",
      video: "https://www.youtube.com/watch?v=37GHTaoknfw",
    },

    {
      area: "chest",
      video: "https://www.youtube.com/watch?v=NePr1XKRTLU",
    },

    {
      area: "glute",
      video: "https://www.youtube.com/watch?v=eRCpceBhcm0",
    },

    {
      area: "foot",
      video: "https://www.youtube.com/watch?v=AXSj_5pBAKw",
    },

    {
      area: "forearm",
      video: "https://www.youtube.com/watch?v=Ayhu7TzNGSQ",
    },

    {
      area: "it band",
      video: "https://www.youtube.com/watch?v=i6Psvd81Hyc",
    },

    {
      area: "hamstring",
      video: "https://www.youtube.com/watch?v=pJUwEBgxWoE",
    },

    {
      area: "tricep",
      video: "https://www.youtube.com/watch?v=SaZK9vlSmHI",
    },

    {
      area: "lat",
      video: "https://www.youtube.com/watch?v=6V5tSn9oEJg",
    },
  ];

  const BUTTONDATA = [
    {
      title: "back",
      embed: "https://www.youtube.com/watch?v=buF1v8aiTvM",
    },

    {
      title: "legs",
      embed: "https://www.youtube.com/watch?v=UIRTPXj1Q1U",
    },

    {
      title: "upper-body",
      embed: "https://www.youtube.com/watch?v=Kpd9ik93Sxk",
    },

    {
      title: "hips",
      embed: "https://www.youtube.com/watch?v=j42sLnoMkrA",
    },
  ];

  return (
    <div className="App">
      <TitleView headline={TITLE} />
      <Search placeholder="What hurts..." data={DATA} />
      <Buttons content={BUTTONDATA} />
    </div>
  );
}

export default App;


Solution 1:[1]

The problem can be solved in two ways. One way is to have a map in app.js on the BUTTONDATA and render separate component for each item of the array. In this way each Button Component will have its own state and will show only its own contents upon button click. The other way is to have a boolean property for each of array item in the BUTTONDATA. and then you can modify your component in the following way:

Button.js

import { useEffect, useState } from "react";
import ReactPlayer from "react-player";

const Buttons = (props) => {
  const { content } = props;
  const [visibilityChanged, setVisibiltyChanged] = useState(false);

  useEffect(() => {}, [visibilityChanged]);

  const handleOnClick = (index) => () => {
    content[index].isVisible = !content[index].isVisible;
    setVisibiltyChanged(!visibilityChanged);
  };

  return (
    <div className="buttonContainer">
      {content.map((item, index) => (
        <div className="buttonSpace" key={index}>
          <button id="btn" onClick={handleOnClick(index)}>
            {item.title}
          </button>
          {item.isVisible ? <ReactPlayer url={item.embed} /> : null}
        </div>
      ))}
    </div>
  );
};

export default Buttons;

and in app.js will have the following changes: App.js

const BUTTONDATA = [
    {
      title: "back",
      embed: "https://www.youtube.com/watch?v=buF1v8aiTvM",
      isVisible: false
    },

    {
      title: "legs",
      embed: "https://www.youtube.com/watch?v=UIRTPXj1Q1U",
      isVisible: false
    },

    {
      title: "upper-body",
      embed: "https://www.youtube.com/watch?v=Kpd9ik93Sxk",
      isVisible: false
    },

    {
      title: "hips",
      embed: "https://www.youtube.com/watch?v=j42sLnoMkrA",
      isVisible: false
    }
  ];

Here is the code sandbox I created to toggle videos on button click.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mohsin Murad