In Short, Let's assume that I have a list of items that I am displaying, and on each item there is a button, like a Quick View button to view extra information about the product in a modal pop-up. Now, everything is working perfectly, except when I click on the button, it brings the information related to the last item of my API/JSON file .. whatever the source of the file is. So, the last item in the Array. when I console.log(index)
it brings the correct index for each card, but it doesn't show the information about each product separately.
import React, { Component } from "react";
import { productsInfo } from "./ProductsData"; // the JS file containing the data
import Modal from "react-modal";
import "./Products.css";
import ProductDetailsPopUp from "./ProductDetailsPopUp";
import axios from "axios";
Modal.setAppElement("#root");
export default class Products extends Component {
state = {
productsData: [],
modalIsOpen: false,
};
OpenModal = () => {
this.setState({ modalIsOpen: true });
};
CloseModal = () => {
this.setState({ modalIsOpen: false });
};
changeProduct = (item, index) => {
this.setState({ showProduct: item });
};
render() {
// const {id, img, title, price, isNew, country, currency} = productsInfo
return (
<div className="ProductsContainer">
{productsInfo.map((item, index) => {
return (
<div className="cardHolder" key={item.id}>
<img src={item.img} alt="Products" />
<button
onClick={() => {
this.OpenModal();
console.log(index);
}}
className="MainProductBtn"
>
QUICK VIEW
</button>
<Modal
key={index}
className="mainModal"
style={{
overlay: {
backgroundColor: "#3333",
opacity: 0.4,
transition: "0.4s",
},
}}
isOpen={this.state.modalIsOpen}
onRequestClose={this.CloseModal}
>
<div className="popupHeader" key={item.id}>
<h3>{item.title}</h3>
<button onClick={this.CloseModal}>×</button>
</div>
<ProductDetailsPopUp />
</Modal>
<p>{item.title}</p>
<small>{`${item.price} USD`}</small>
</div>
);
})}
</div>
);
}
}
I tried including the index in onClick function and also passing it in the state, didn't work
You create Modal
for every item inside your map
method meaning that it will display productsInfo.length
modals and the last one will be on top.
Remote Modal
tag from the map
method and onClick
set the current item at your state, change the display of the dialog to true
and read the current item from the state inside your Modal
.
e.g.
state = {
productsData: [],
modalIsOpen: false,
currentItem: null
};
OpenModal = item => {
this.setState({ modalIsOpen: true, currentItem: item });
};
onClick={() => {
this.OpenModal(item);
console.log(index);
}}