Let me start off by saying that I did look for other topics but I haven't found a solution yet so I'd like to walk through this with you guys.
I have a simple website with a search bar, a search result list and a div where I display the item I click in the result list.
The issue starts when I click an item in the results list. I need to click it twice for it to update the div where I display the item.
What happens when I click an item from the search results list:
const getProductById = (store) => {
if (store == "STORENAME") {
Axios.get(
`http://localhost:3001/get-storename-product-by-id/${productId}`
).then((response) => {
console.log(response.data);
setProductResultList(response.data);
setProductTitle(response.data[0].title);
setProductImg(response.data[0].imageSrc);
setFinalProductId(response.data[0].productId);
});
} else {
Axios.get(`http://localhost:3001/get-storename-product-by-id/${productId}`).then(
(response) => {
console.log(response.data);
setProductResultList(response.data);
setProductTitle(response.data[0].title);
setProductImg(response.data[0].imageSrc);
setFinalProductId(response.data[0].productId);
}
);
}
};
The function fetches all the data linked to the productId of the clicked product (this returns all the historic data I have on the item in an array with objects (1 object for each row)).
How I show the item on the page:
<div className="item">
<div>
<img
src={productImg}
alt={productTitle}
width="250px"
height="250px"
/>
<p className="product-id-span">
Product Id: {finalProductId}
</p>
<p className="m-0">Product name:</p>
<p>{productTitle}</p>
<div className="historical-info">
<span>latest prices:</span>
<div className="table-responsive">
<table class="table text-white">
<thead>
<tr>
<th scope="col">Price</th>
<th scope="col">Date</th>
</tr>
</thead>
<tbody>
{productResultList.map((val, key) => {
let parsedPrice = parseInt(val.price);
let parsedPriceInEuros = parsedPrice / 100;
const finalPrice = new Intl.NumberFormat(
"de-DE",
{ style: "currency", currency: "EUR" }
).format(parsedPriceInEuros);
return (
<tr>
<td>
Price:
{val.store == "STORENAME"
? finalPrice
: val.price}
</td>
<td>{val.date}</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
</div>
</div>
What I've tried:
I tried to only set state to the productResultList in the getProductById function, and set the other state when the useEffects note changes to the productResultList.
useEffect(() => {
setProductTitle(productResultList[0].title);
setProductImg(productResultList[0].imageSrc);
setFinalProductId(productResultList[0].productId);
}, [productResultList]);
Could someone perhaps explain what I'm doing wrong or what's the right way to do this?
Note:
- I changed the real store names to STORENAME because it's not neccessary in this example.
- resultList = the list with results when I search, productResultList is the list with objects of the clicked product.