Реагировать: Как отобразить индекс массива, представляющего собой объект, содержащий изображение

#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, и это работает…