How to display only 3 elements from the array instead of 5 and how to make these elements randomly change after the timer expires? I understand that I need to create a function that pulls 3 random entries from the list, but how to implement this in practice? I used use-local-storage implementation. Thank you for answers!
This is my code:
const CurrentEventsItem = () => {
const [timeLeft, setTimeLeft] = useLocalStorage('timer', 5 * 60)
const getPadTime = (time) => time.toString().padStart(2, '0')
const minutes = getPadTime(Math.floor(timeLeft / 60))
const seconds = getPadTime(timeLeft - minutes * 60)
useEffect(() => {
const interval = setInterval(() => {
setTimeLeft((timeLeft) => (timeLeft >= 1 ? timeLeft - 1 : setDisabled() || 5 * 60))
}, 1000)
return () => clearInterval(interval)
}, [])
const [appState, changeState] = useLocalStorage('CurrentEventsItem', {
objects: [
{id: v4(), title: 'Apple iPhone 13 Pro Max 256Gb (небесно-голубой)', avatar: 'https://cdn-icons-png.flaticon.com/512/147/147144.png', statusItem: false},
{id: v4(), title: '500 Stars', avatar: 'https://cdn-icons-png.flaticon.com/512/147/147144.png', statusItem: false},
{id: v4(), title: 'Sony PlayStation 5 Digital Edition', avatar: 'https://cdn-icons-png.flaticon.com/512/147/147144.png', statusItem: false},
{id: v4(), title: 'XBOX 360 Digital Edition', avatar: 'https://cdn-icons-png.flaticon.com/512/147/147144.png', statusItem: false},
{id: v4(), title: 'Google Nexus Digital Edition', avatar: 'https://cdn-icons-png.flaticon.com/512/147/147144.png', statusItem: false}
]
})
const toggleActive = (index) => {
let arrayCopy = [...appState.objects];
arrayCopy[index].statusItem = !arrayCopy[index].statusItem;
changeState({...appState, objects: arrayCopy});
}
const toggleActiveStyles = (index) => {
if (appState.objects[index].statusItem) {
return 'current__events__hot-price disabled'
} else {
return 'current__events__hot-price'
}
}
const toggleActiveStylesBtns = (index) => {
if (appState.objects[index].statusItem) {
return 'current__events__btn-green disabled'
} else {
return 'current__events__btn-green'
}
}
const setDisabled = () => {
appState.objects.forEach((item, index) => {
if (item.statusItem) {
toggleActive(index);
}
});
}
return (
<>
<div className='current__events__wrapper'>
{appState.objects.map((item, index) =>
<div className="current__events__hot-price__item" key={index}>
<div className={toggleActiveStyles(index)}>
<h5 className="current__events__card-title__large">Hot Price</h5>
</div>
<div className="current__events__image">
<img src={item.avatar} alt='user' className="rounded-circle" width='75' height='75'/>
</div>
<div className="current__events__info">
<h4 className="current__events__title__middle">{item.title}</h4>
</div>
<div className="current__events__timer">
<span>{minutes}</span>
<span>:</span>
<span>{seconds}</span>
</div>
<button className={toggleActiveStylesBtns(index)} onClick={() => toggleActive(index)} disabled={item.statusItem}>СДЕЛАТЬ ХОД</button>
</div>
)}
</div>
</>
)
}
export default CurrentEventsItem
CodePudding user response:
You can first create a state selectedItems
which will contain random 3 elements.
const [selectedItems, setSelectedItems] = useState(() =>
getRandomElements(appState.objects, 3)
);
then using useEffect
hook you can change state if the timer reaches 0
useEffect(() => {
if (timeLeft === 0) {
const elements = getRandomElements(appState.objects, 3);
setSelectedItems(elements);
}
}, [timeLeft, appState.objects]);
I'm passing state from the parent component and toggling the state based on id instead of index as:
const toggleActive = (item) => {
let arrayCopy = [...appState.objects];
const toggledElement = arrayCopy.find((o) => o.id === item.id);
if (toggledElement) {
toggledElement.statusItem = !toggledElement.statusItem;
changeState({ ...appState, objects: arrayCopy });
}
};