In react/nextjs I have click Event for a button I'm trying to use setState and change an array and it fires up after two clicks Here is the state array I have
const [arrayClicked, setArrayClicked] = useState(["image-id-0", "image-id-1", "image-id-2", "image-id-3"]);
["image-id-0", "image-id-1", "image-id-2", "image-id-3"]
so the plan is to remove the first element and push in a new element from the back so it would be ["image-id-1", "image-id-2", "image-id-3", "image-id-4"]
then ["image-id-2", "image-id-3", "image-id-4", "image-id-5"]
etc
So if I use the JS mutation of the array and not the setState as:
arrayClicked.shift();
arrayClicked.push("image-id-4");
// I know that this is not the correct way of working with React but it works from the first click
this works directly from the first click of the button. But when I try to use setState I have to press twice for it fire up
this is my setState code:
const newIDImg = "image-id-4"; // example normally they are actual ID values for images
setArrayClicked(prev => {
const prevArray = prev.filter(val => {
return val !== prev[0];
});
return [...prevArray, newIDImg];
});
// even if I try slice same problem it fires up after second click
setArrayClicked(prev => [
...prev.slice(1, prev.length),
newIDImg
]);
Here is the full set of code:
import { useState } from "react";
// props.product.images is 13 in length so index from 1 to 13 so keeping it as read only
const [displaySmallerImages, setDisplaySmallerImages] = useState(props.product.images.slice(0, 4));
const [arrayClicked, setArrayClicked] = useState(['image-id-0', 'image-id-1', 'image-id-2', 'image-id-3']);
const handleRightClick = () => {
// example props.product.images is 13 in length
const exampleFakeIndex = 3;
let newIDImg, tempArray;
if (props.product.images[exampleFakeIndex + 1] !== undefined) {
newIDImg = props.product.images[exampleFakeIndex + 1].id;
// arrayClicked.shift(); // TODO FIX THIS TO USE setArrayClicked INSTEAD!!
// arrayClicked.push(newIDImg); // TODO FIX THIS TO USE setArrayClicked INSTEAD!!
setArrayClicked(prev => {
const prevArray = prev.filter(val => {
return val !== prev[0];
});
return [...prevArray, newIDImg];
});
// AS displaySmallerImages IS ARRAY OF OBJECT THIS IS A HELPER FUNCTION WHICH DISPLAYS THEM AS
tempArray = helperArrayNewSetOfFours(arrayClicked, props.product.images);
// helperArrayNewSetOfFours just returns an array of object of {id, imgName, imgData}
setDisplaySmallerImages(tempArray);
} else {
newIDImg = props.product.images[0].id;
// arrayClicked.shift(); // TODO FIX THIS TO USE setArrayClicked INSTEAD!!
// arrayClicked.push(newIDImg); // TODO FIX THIS TO USE setArrayClicked INSTEAD!!
setArrayClicked(prev => [
...prev.slice(1, prev.length),
newIDImg
]);
tempArray = helperArrayNewSetOfFours(arrayClicked, props.product.images);
setDisplaySmallerImages(tempArray);
}
}
The helperFunction helperArrayNewSetOfFours
is basically a function with returns an array of object for the new array of objects to be displayed and then passed to the displaySmallerImages
array through the setDisplaySmallerImages
incase you want to see what the helperArrayNewSetOfFours
is:
const helperArrayNewSetOfFours = (oldFour, fullArraySize) => {
const arrayTemp = [];
oldFour.forEach((val, ind) => {
fullArraySize.forEach(img => {
if (val === img.idImage) {
arrayTemp.push({
id: img.id,
imgName: img.imgName,
imgData: img.imgData
});
}
});
});
return arrayTemp;
}
returns:
//THE OLD
array = [
{ id: "image-id-1", imgName: "name1", imgData: ARRAY BUFFER },
{ id: "image-id-2", imgName: "name2", imgData: ARRAY BUFFER },
{ id: "image-id-3", imgName: "name3", imgData: ARRAY BUFFER },
{ id: "image-id-4", imgName: "name4", imgData: ARRAY BUFFER }
];
// The new array because of the helper function returns
//THE NEW IT RETURNS!!
array = [
{ id: "image-id-2", imgName: "name2", imgData: ARRAY BUFFER },
{ id: "image-id-3", imgName: "name3", imgData: ARRAY BUFFER },
{ id: "image-id-4", imgName: "name4", imgData: ARRAY BUFFER },
{ id: "image-id-5", imgName: "name5", imgData: ARRAY BUFFER }
];
So why does setState force two click before the values registers and it fires up? While array mutation JS the .shift() and .push()
fires up directly from the first click? How can I make the setState to work directly from the first click?