So, I am trying to add max 3 values to a useState array and ensure all are unique and if fourth unique element is pushed it will replace the first element at index 0. ? Also, if the same element is clicked then it is removed from the array. However the function I wrote is not able to accomplish my objective.
const [chatbox,setChatBox]=useState([]);
chat=['a11','b11','c11','d11']
chat.map((c)=>(
<div
onClick={()=>addorRemoveitems(c)}
>
{c}
<div>
))
const addorRemoveitems=(cId)=>{
if (
chatbox.length <= 3 &&
chatbox.includes(cId)
) {
const newArray = chatbox.filter(
(c) => c !== cId
);
setChatBox(newArray);
} else if (
chatbox.length < 3 &&
chatbox.indexOf(cId) === -1
) {
setChatBox((prev) => [...prev, cId]);
} else if (
chatbox.length == 3 &&
chatbox.indexOf(cId) !== -1
) {
const newArray = chatbox.splice(
0,
1,
cId
);
setChatBox(newArray);
}
}
You'll have to modify this a tad I guess to fit how you are adding new items to the list. Here is a working example: https://codesandbox.io/s/react-hooks-playground-forked-e32wlp?file=/src/index.tsx
const [array, setArray] = useState([]);
const [newItemGen, setNewItemGen] = useState(0);
const addOrRemoveItemFromArray = (item) => {
if (array.includes(item)) {
setArray((prevState) =>
prevState.filter((existing) => existing !== item)
);
} else {
setArray((prevState) => [item, ...prevState.slice(0, 2)]);
setNewItemGen((prevState) => prevState + 1);
}
};
return (
<div style={{ display: "flex", flexDirection: "column" }}>
<div>
Items in array :
{array.map((item) => (
<button onClick={() => addOrRemoveItemFromArray(item)}>{item}</button>
))}
</div>
<div>
<button
onClick={() => addOrRemoveItemFromArray(`newItem${newItemGen}`)}
>
add item
</button>
</div>
</div>
);
}
If the item is already in the array, filter it out. If not, add the item to a slice of the old array which only captures the first two values.
EDIT: I just realised you want to check that a value is unique before adding it to the list. You'll have to create a function for adding and function for removing then.
const addItem = (item) => {
if (!array.includes(item)) {
setArray((prevState) => [item, ...prevState.slice(0, 2)]);
setNewItemGen((prevState) => prevState + 1);
}
};
const removeItemFromArray = (item) => {
setArray((prevState) =>
prevState.filter((existing) => existing !== item)
);
};