#javascript #arrays #reactjs
Вопрос:
У меня есть коллекция изображений, которые я использую для заполнения компонента карусели, который я пытаюсь создать:
const images = [{img: 'url'},{img: 'url'},{img: 'url'}];
Мне бы хотелось создать обработчик для кнопки (next и prev), который мог бы перейти к середине, а затем к началу и повторить.
Раньше я делал что-то подобное:
const handleNext = () => {
let newg = [...gallery];
if (activeIdx == gallery.length - 1) {
setActiveIdx(val => val = -1)
}
if (activeIdx != gallery.length / 2) {
setActiveIdx(val => val nextBatch)
setIsNext(isNext => !isNext);
let splice = newg.splice(nextBatch - 1);
setGallery(() => [...splice, ...newg]);
} else {
setActiveIdx(0)
}
}
Вскоре я понял, что это действительно имитирует эффект перехода к точке в массиве, но поскольку он генерирует новый массив и добавляет его в DOM, применение анимации к действию, например, ослабление, не имеет никакого эффекта. Поскольку он не перемещается в часть массива; начальная точка в представлении div/представления становится новой начальной точкой в массиве после соединения.
Часть, о которой идет речь:
let splice = newg.splice(nextBatch - 1);
setGallery(() => [...splice, ...newg]);
Это все в codesandbox.
Это весь мой компонент:
import React, { useEffect, useState, useRef } from 'react';
import cx from 'classnames';
const images = [{img: 'url'},{img: 'url'},{img: 'url'}];
const Carousel = () => {
const [items, setItems] = useState(() => Array.from(Array(images.length).keys()));
const [gallery, setGallery] = useState(images);
const [nextBatch, setNextBatch] = useState(null);
const [amountOfDots, setAmountOfDots] = useState(1);
const [isNext, setIsNext] = useState(true)
const [activeIdx, setActiveIdx] = useState(0);
const handleNext = () => {
console.log("items ", items);
if (activeIdx == gallery.length - 1) {
setActiveIdx(val => val = -1)
}
if (activeIdx != gallery.length / 2) {
setActiveIdx(val => val nextBatch)
setIsNext(isNext => !isNext)
} else {
setActiveIdx(0)
}
}
const createItem = (idx) => {
const item = {
image: gallery[idx].image,
title: gallery[idx].title
};
return item;
};
const CarouselSlideItem = ({ idx }) => {
const item = createItem(idx);
return (
<>
<div className={styles.frame} style={item.styles}>
<img src={item.image} alt={item.title} />
</div>
<div className={styles.carouselSlideItem__body}>
<p> {item.title}</p>
</div >
</>
);
};
useEffect(() => {
var arrayLength = items.length;
if (arrayLength % 2 === 0) {
setAmountOfDots(2)
setNextBatch(items[arrayLength / 2])
}
}, [activeIdx]);
return (
<div className={styles.wrapper}>
<div ref={nodeRef} className={styles.carousel}
style={isGalleryWidthInline ? {
maxWidth: '465px'
} : null}
>
<div className={styles.carousel__inner} >
{
items.map((pos, i) => (
<CarouselSlideItem
key={i}
idx={i}
/>
))
}
</div>
<button onClick={() => console.log('bar')} className={cx(styles.nav, styles.prev)}><i className={`fas fa-chevron-left fa-2x ${styles.icon}`}></i></button>
<button onClick={() => handleNext()} className={cx(styles.nav, styles.next)}><i className={`fas fa-chevron-right fa-2x ${styles.icon}`}></i></button>
</div>
<ul className={styles[`carousel__dots`]}>
{Array.from(Array(amountOfDots).keys()).map((dot) => {
return (
<li className={styles.dot} onClick={() => { console.log('foo') }} />
)
})}
</ul>
</div>
);
};
export default Carousel;
Итак, как бы вы создали обработчик, который будет переходить к части массива?
Комментарии:
1. Я не уверен, что это только здесь, но я не могу запустить ваш фрагмент кода и коробки. Он продолжает «Устанавливать зависимости 1/18 (веб-параметры)».
2. @testing_22 Спасибо за регистрацию… Я проверил это на своем телефоне и в нескольких браузерах на своем MacBook, и это работает…