@HelpMeeee

Анимация бесконечного slider next js, как работать с классами в массиве объектов?

Изучаю Next.JS, занялся анимацией, есть пару вопросов, которые не могу решить. Задача сделать бесконечный не интерактивный слайдер иконок криптовалюты, бесконечность и анимацию прокрутки мне вроде бы удалось реализовать, но я думаю можно лучше. Застрял на добавлении класса первому элементу, первый элементы долежн быть выделен более ярким бекграундом и величиной иконки. Первый элемент должен анимировано скинуть класс main и уйти за предел видимости пользователя, а второй элемент должен стать анимировано на его место и получить класс main. Бесконечная прокрутка работает, а вот как реализовать добавление классов в pages я нигде не найду.

Так же есть вопрос по key, сыпет в консоль предупреждение, что кей не уникален в самом последнем return. Во-первых, я не пойму зачем там key, во-вторых, я не пойму как это пофиксить.
Еще очень интересует момент как выключить двойной вызов setTimeout в dev mode

import { StyledCardList, StyledSecondaryCard } from './styled'
    import React from "react";
    import { useState, useEffect } from "react";
    import cardDetails from "./swiperconfig"
         
    const TRANSITION_DURATION = 1500;
      
    export const Carousel = () => {
const [pages, setPages] = useState([])
const [offset, setOffset] = useState(0)
const [transitionDuration, setTransitionDuration] = useState(TRANSITION_DURATION)

const handleTransitionEnd = () => {
  setOffset(0);
  setTransitionDuration(0);
  console.log(offset)
}
useEffect(() => {
  if (transitionDuration === 0) {
    setTimeout(() => {
      setTransitionDuration(TRANSITION_DURATION)
    }, TRANSITION_DURATION)
  }
}, [transitionDuration])
useEffect(() => {
  setTimeout(() => {
    setOffset((currentOffset) => {
      const newOffset = currentOffset - 30;
      console.log(pages);
      pages[1] = () => {
        return(
          <StyledSecondaryCard key={cardDetails.id} className="card">
          <img key={cardDetails.id} className="image" src={cardDetails.imgUrl} alt={cardDetails.alt} />
          </StyledSecondaryCard>
        )
      }

      return (newOffset);
    })
  }, 5000)
  pages.push(pages[0]);
  pages.shift(pages[0]);
  if (offset != 0){
    setTimeout(() => {
      setTransitionDuration(0)
      setOffset(0)
    }, 15000)
  }
}
)

useEffect(() => {
  let curr = -1;
  setPages(
    cardDetails.map(() => {
      curr++;
      if (curr == 1){
        return (
          <StyledSecondaryCard key={cardDetails.id} className="card main">
          <img key={cardDetails.id} className="image" src={cardDetails.imgUrl} alt={cardDetails.alt} />
          </StyledSecondaryCard>
        )
      }
      else{
        return(
          <StyledSecondaryCard key={cardDetails.id} className="card">
            <img key={cardDetails.id} className="image" src={cardDetails.imgUrl} alt={cardDetails.alt} />
          </StyledSecondaryCard>
        )
      }
      })
  )
}, [])
// useEffect(() => {
// },[])
let data = new Date();

return (
  <div style={{maxWidth: '710px', overflow: 'hidden'}}>
      <StyledCardList key={offset * data} className="cardList" sx={{
        marginLeft: "-50px",
        transform: `translateX(${offset}px)`,
        transitionDuration: `${transitionDuration}ms`
      }} onTransitionEnd={handleTransitionEnd} onTransitionEndCapture={handleTransitionEnd}>
        {pages}
      </StyledCardList>
  </div>
)
  • Вопрос задан
  • 84 просмотра
Решения вопроса 1
alexey-m-ukolov
@alexey-m-ukolov Куратор тега React
Основной проблемой я тут вижу то, что вы в state храните компоненты. Так не делать не надо, в state нужно хранить данные, а из них уже рендерить нужное. Тогда вы и классы сможете гибко добавлять какие надо и что угодно.

Так же есть вопрос по key, сыпет в консоль предупреждение, что кей не уникален в самом последнем return. Во-первых, я не пойму зачем там key, во-вторых, я не пойму как это пофиксить.
Вы рендерите элементы массива (pages), и, чтобы отличать их друг от друга, Реакту нужен какой-то идентификатор (подробнее в документации). У вас он как бы есть, но, во-первых, как сказано выше, его ломает то, что вы храните в state уже отрендеренные компоненты, а во-вторых, вы в качестве ключа для всех элементов используете одно и то же значение (cardDetails.id), а оно должно быть уникальным.

как выключить двойной вызов setTimeout в dev mode
Не надо его выключать, надо корректно чистить таймауты, для отлова таких проблем двойной вызов и делают.

Видимо, вы запутались и вам кажется, что вы изучаете Next.js, а на самом деле вы изучаете React (от Next в вашем коде нет абсолютно ничего) и вам явно нужно вернуться к документации и прочитать её от начала и до конца, там есть и ответы на ваши вопросы и примеры.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы