render image on button click in react

Viewed 1979

I have the following code with 3 buttons and 3 images each button corresponding to each image now I want to render each image only on button click but have no idea how to do it. I have the following code.

import React from 'react';
import img5 from '../../Assets/Ground.png'
import img6 from '../../Assets/First.png'
import img7 from '../../Assets/Second.png'

const Location = () => {

    return (
        <div>
            <div className="Ccontainer">
            <button onClick className="ground" >Ground Floor</button>
            <button onClick className="ground">First Floor</button>
                <button onClick className="ground">Second Floor</button>
            </div>
                 <div className= "image">
                <img src={img5} alt="ground" />
                <img src={img6} alt="first" />
                <img src = {img7 } alt= "second" />
                
                </div>
            
            
    </div>
    );
};

export default Location;
4 Answers

Here is how I would do it:

import React, { useState } from "react";
import img5 from "../../Assets/Ground.png";
import img6 from "../../Assets/First.png";
import img7 from "../../Assets/Second.png";

const Location = () => {
  const [imageClicked, setImageClicked] = useState({
    first: false,
    second: false,
    ground: false
  });
  const onClickHandler = (order) => {
    setImageClicked((prevState) => ({
      ...prevState,
      [order]: !prevState[order]
    }));
  };
  return (
    <div>
      <div className="Ccontainer">
        <button onClick={() => onClickHandler("ground")} className="ground">
          Ground Floor
        </button>
        <button onClick={() => onClickHandler("first")} className="ground">
          First Floor
        </button>
        <button onClick={() => onClickHandler("second")} className="ground">
          Second Floor
        </button>
      </div>
      <div className="image">
        {imageClicked.ground && <img src={img5} alt="ground" />}
        {imageClicked.first && <img src={img6} alt="first" />}
        {imageClicked.second && <img src={img7} alt="second" />}
      </div>
    </div>
  );
};

export default Location;

I do not have the assets, but feel free to add them here and play with the solution.

With a little bit of details, we use the imageClicked state to save the state of clicked/unclicked for each image.

const [imageClicked, setImageClicked] = useState({
    first: false,
    second: false,
    ground: false
  });

We use the onClickHandler as the onClick function that gets the corresponding image key and use it to update only this part of the state object with the opposite of it it has been before, so if it was true it will be false and vice versa.

  const onClickHandler = (order) => {
    setImageClicked((prevState) => ({
      ...prevState,
      [order]: !prevState[order]
    }));
  };

With this state we condition the rendering of the image so it will only show if imageClicked.X where X is first/second/ground

<div className="image">
        {imageClicked.ground && <img src={img5} alt="ground" />}
        {imageClicked.first && <img src={img6} alt="first" />}
        {imageClicked.second && <img src={img7} alt="second" />}
</div>

If you want only one image to appear at a time please use this onClick function instead, to make all image state to false other than the clicked image.

  const onClickHandler = (order) => {
    const resetImages = {
      first: false,
      second: false,
      ground: false
    }
    setImageClicked({
      ...resetImages,
      [order]: true
    });
  };

if you have many images and buttons you can make it into an array and use map

here I created a sample codesandbox

import React, {useState} from 'react';
import img5 from '../../Assets/Ground.png'
import img6 from '../../Assets/First.png'
import img7 from '../../Assets/Second.png'

const Location = () => {

    const imgArr = [
     {
      id: 'groundFloor',
      image: img5
     }, 
     {
      id: 'firstFloor',
      image: img6
     }, 
     {
      id: 'secondFloor', 
      image: img7
     }
    ]

    const [open, setOpen] = useState(null);

    const [showImage, setShowImage] = useState({
      showImageNow: true,
      showImageId: null,
    })

    const {showImageNow, showImageId} = showImage;

    const OpenImage = (a) => {
     setOpen(a.image);
     setShowImage({
       showImageNow: !showImageNow,
       showImageId: a.id
     });
    }

    return (
      <div>

         {imgArr.map((a, i) => 
           <div key={i}>

             <button 
              onClick={() => OpenImage(a)}
              className="ground" 
             >
              {a.id}
             </button>

             <br />
        
             {showImageNow && showImageId === a.id ?
               <img
                src={open} 
                alt={a.id} 
               />
             :null}
           </div>
         )}
      </div>
    );
};

export default Location;

Just make array in state and change it according to click on button, and use conditional rendering for images:

import React from 'react';
import img5 from '../../Assets/Ground.png'
import img6 from '../../Assets/First.png'
import img7 from '../../Assets/Second.png'

const Location = () => {
const [displayImages, setDisplayImages] = React.useState({img5: false, img6: false, img7:false});
    return (
        <div>
            <div className="Ccontainer">
            <button onClick={()=>setDisplayImages({...displayImages, img5:true})} className="ground" >Ground Floor</button>
            <button onClick={()=>setDisplayImages({...displayImages, img6:true})} className="ground">First Floor</button>
                <button onClick={()=>setDisplayImages({...displayImages, img7:true})} className="ground">Second Floor</button>
            </div>
                 <div className= "image">
              {displayImages.img5 &&  <img src={img5} alt="ground" />}
               {displayImages.img6 && <img src={img6} alt="first" />}
               {displayImages.img7 && <img src = {img7 } alt= "second" />}
                
                </div>
            
            
    </div>
    );
};

export default Location;

You can use a function to render images. And when you click on the button, you pass a number like this for example:

onClick={renderImage(5)}

function renderImage(nb) {
  swith(nb){
    case 5:
      return ( <img src={img5} alt="ground" /> )
      break;
    ...
    ...
  }
} 

Not the best solution but perhaps can help you. :)

Related