Home > database >  Data-bind Image in React
Data-bind Image in React

Time:04-07

I started learning React recently. I made a page with Images. When I click on the images it opens a Modal, and my plan is to display the related image in the Modal.

So basically my idea is to data-bind the image to the Modal.

The question is: How could I bind the images to the Modal function?

The modal: Modal.jsx

const Modal = ({ setIsOpen }) => {
    return (
      <>
        <div onClick={() => setIsOpen(false)} className={styles.ewn__darkBG}/>
        <div className={styles.ewn__centered}>
          <div className={styles.ewn__modal}>
            <div className={styles.ewn__modalHeader}>
              <h5 className={styles.ewn__heading}>Dialog</h5>
            </div>
            <button className={styles.ewn__closeBtn} onClick={() => setIsOpen(false)}>
              <RiCloseLine style={{ marginBottom: "-3px" }} />
            </button>
            <div className={styles.ewn__modalContent}>
              I would like to display image here available in the Vocabulary.js
            </div>
            <div className={styles.ewn__modalActions}>
              <div className={styles.ewn__actionsContainer}>
                <button
                  className={styles.ewn__cancelBtn}
                  onClick={() => setIsOpen(false)}
                >
                  Cancel
                </button>
              </div>
            </div>
          </div>
        </div>
      </>
    );
  };
  
  export default Modal;

The page: Vocabulary.js

Explanation: I imported image files, put them in an array and display them with mapping.

const IMAGES = [
    {img: Vocab1 }, {img: Vocab2 } , {img: Vocab3 } ,  {img: Vocab4 },  {img: Vocab5 }, 
    {img: Vocab6 },  {img: Vocab7 },  {img: Vocab8 },  {img: Vocab9 },  {img: Vocab10 },
    {img: Vocab11 },  {img: Vocab12 },  {img: Vocab13 },  {img: Vocab14 },  {img: Vocab15 },
    {img: Vocab16 },  {img: Vocab17 },  {img: Vocab18 },  {img: Vocab19 },  {img: Vocab20 },
    {img: Vocab21 },  {img: Vocab22 },  {img: Vocab23 },  {img: Vocab24 }
];

    const Vocabulary = () =>{
      const [isOpen, setIsOpen] = useState(false);
        return <>
    
    <div > 
    {IMAGES.map(IMAGES=> {
    return (
      
        <> 
        <div className="card vocabulary--card mt-5 mb-5 me-5 ms-5">
        <img src={IMAGES.img} alt="Vocab1" className="card-img-top" onClick={() => setIsOpen(true)}/>
      <div className="card-body">
        {isOpen && <Modal setIsOpen={setIsOpen} />}
      </div>
    </div>

</> 
)
})}
</div>

   </>
}

The web page: Vocabulary.js enter image description here

The modal at the moment: Modal.jsx enter image description here

P.S.: I don't use bootstrap because for some reason it displays only the first image everywhere, and the second reason is that I would like to practise React.

CodePudding user response:

const Vocabulary = () => {
  const [isOpen, setIsOpen] = useState(null);
  return (
    <>
      <div >
        {IMAGES.map((imageData) => {
          return (
            <>
              <div className="card vocabulary--card mt-5 mb-5 me-5 ms-5">
                <img
                  src={imageData.img}
                  alt="Vocab1"
                  className="card-img-top"
                  {/* send the clicked image data to the state */}
                  onClick={() => setIsOpen(imageData)}
                />
                <div className="card-body">
                  <p
                    className="card-text dropdown-toggle"
                    type="button"
                    id="dropdownMenuButton1"
                    data-bs-toggle="dropdown"
                    aria-expanded="false"
                  ></p>
                  {Boolean(isOpen) && (
                    {/* bind the selected image data state to a data prop on Modal */}
                    <Modal setIsOpen={setIsOpen} data={isOpen} />
                  )}
                </div>
              </div>
            </>
          );
        })}
      </div>
    </>
  );
};

You could set the clicked item in the state instead of a boolean. This way you could share the selected image data to the modal by adding a prop to the Modal which accepts this data.

CodePudding user response:

Vocabulary.js

const Vocabulary = ( ) => {
  const [isOpen, setIsOpen] = useState(null);

  return (
    <>
      <div >
        {IMAGES.map((imageData) => {
          return (
            <>
              <div className="card vocabulary__card mt-5 mb-5 me-5 ms-5">
                <img
                  src={imageData.img}
                  alt="Vocab1"
                  className="card-img-top vocabulary--img"
                //  {/* send the clicked image data to the state */}
                  onClick={() => setIsOpen(imageData)}
                />
                <div className="card-body">
                
                  {Boolean(isOpen) && (
                    //  bind the selected image data state to a data prop on Modal
                    <Modal
                      data={isOpen} image={isOpen.img}
                      //  close the modal
                      setIsOpen={setIsOpen}
                      
                    />
                  )}

                </div>
              </div>
            </>
          );
        })}
      </div>
    </>
  );
};

Modal.jsx

  const Modal = ({ image, setIsOpen }) => {
      return (
        <>
          <div onClick={() => setIsOpen(false)} className={styles.ewn__darkBG}/>
          <div className={styles.ewn__centered}>
            <div className={styles.ewn__modal}>
              <div className={styles.ewn__modalHeader}>
              
              </div>
              <button className={styles.ewn__closeBtn} onClick={() => setIsOpen(false)}>
                <RiCloseLine style={{ marginBottom: "-3px" }} />
              </button>
              <div className={styles.ewn__modalContent}>
                <img className={styles.ewn_modal_img} src={image} alt="modal" />
              </div>
              <div className={styles.ewn__modalActions}>
                <div className={styles.ewn__actionsContainer}>
                </div>
              </div>
            </div>
          </div>
        </>
      );
    };
    
    export default Modal;
  • Related