I have an API endpoint that returns 20 items. I make a call and store these items as an array called my "items" on the state. I want to show 4 items at a time and then when a user clicks on the particular node it will remove said item from the list being displayed and replace it with another item from the array that hasn't been used.
The tricky part I'm facing is referencing the exact location that the item has been removed from. For example, if from my 4 items I click on item 2 to be removed I want to randomly select an item that hasn't been used and add it in the location that item two was, rather than sliding everything up and it becoming item 4.
How would I go about doing this? thanks for you help.
----- ANSWER -------
Thanks everyone and in-particular @wdm for sending me in the right direction. It answered a large chunk of my question, however it looped back through the results. I wanted to select items that haven't been used.
I added a little more functionality to the state in order to track the items being displayed and the items already used.
note: I've tweaked the "replaceItem" method as the while loop had a memory leak once it reached the end of the list. The else statement runs after we've already shown every one of the items and thus can go ahead and start to remove them from being shown to the user.
state = {
companies: [
{ id: 1, name: "Chris" },
{ id: 2, name: "Ringo" },
{ id: 3, name: "John" },
{ id: 4, name: "Marty" },
{ id: 5, name: "Beetlejuice" },
{ id: 6, name: "Dwayne" },
{ id: 7, name: "Spud" },
{ id: 8, name: "Ant" },
{ id: 9, name: "Spaghetti" },
{ id: 10, name: "Meatballs" }
],
items: [],
usedItems: []
};
componentDidMount() {
this.generateList();
}
generateList = () => {
const { companies } = this.state;
let items = Object.keys(companies.slice(0, 4));
this.setState({
items,
usedItems: items
});
};
replaceItem = i => {
const { companies, items, usedItems } = this.state;
let newItem = null;
if (companies.length !== usedItems.length) {
while (newItem === null) {
let newCount = Math.floor(
Math.random() * companies.length
).toString();
if (usedItems.indexOf(newCount) === -1) {
newItem = newCount;
}
}
let newItems = [...items];
newItems[i] = newItem;
this.setState(prevState => {
return {
items: newItems,
usedItems: [...prevState.usedItems, newItem]
};
});
} else {
this.setState(prevState => {
return {
items: prevState.items.filter(
item => items.indexOf(item) !== i
)
};
});
}
};