alaskafx
@alaskafx
Не .do Frontend

Как решить проблему одинаковых ключей?

Есть подобный компонент:
import styles from "@views/home-page/ui/banner/ui/Banner.module.css";
import { bannerContent } from "@/src/views/home-page/ui/banner/config";
import { AnimatePresence, motion } from "framer-motion";

const animationVariant = {
  transition: { type: "spring", stiffness: 100 },
  initial: { opacity: 0, y: 60 },
  animate: { opacity: 1, y: 0 },
  exit: { opacity: 0, y: -60 },
};

export const BannerContent = ({ currentSlide }: { currentSlide: number }) => {
  const { subTitle, title } = bannerContent[currentSlide];

  return (
    <>
      <AnimatePresence mode="wait">
        <motion.p
          variants={animationVariant}
          key={`subtitle-${subTitle}`}
          initial="initial"
          animate="animate"
          exit="exit"
          transition={{ duration: 0.3, ease: "easeInOut" }}
          className={styles.bannerSubtitle}
        >
          {subTitle}
        </motion.p>
      </AnimatePresence>
      <AnimatePresence mode="wait">
        <motion.h1
          key={`title-${title}`}
          variants={animationVariant}
          initial="initial"
          animate="animate"
          exit="exit"
          transition={{ delay: 0.1, duration: 0.3, ease: "easeInOut" }}
          className={styles.bannerTitle}
        >
          {title}
        </motion.h1>
      </AnimatePresence>
    </>
  );
};


Суть в том, что контент title и subTitle может меняться динамически. Его смена зависит от скролла, а соответственно, что лихой юзверь может начать быстро скроллить вверх-вниз (контент меняется от скролла по вертикали). Тогда получается, что если представить такую ситуацию, когда скроллят очень быстро, то возникает момент, когда этих p и h1 становится по 3 штуки.
Выявил проблему тем же быстрым скроллом и понял, что у первого элемента (к примеру p), который уже уезжает из-за анимации может быть ключ "1", у второго, который вот-вот начинает уезжать ключ "2", а уже третий (который новый) тоже имеет ключ "1", так как пользователь скроллил вверх-вниз быстро и элементы с ключом "1" имеют одинаковый текст.
Результат таков, что фреймер ломается и перестает что-либо показывать без ошибок в консоли/начинает стакать элемент по "500 в ряд"

Как такое решить? Ссылка на пен

Мне просто нужно, чтобы был эффект уходящего старого текста и приходящего нового текста
  • Вопрос задан
  • 232 просмотра
Решения вопроса 1
alexey-m-ukolov
@alexey-m-ukolov Куратор тега React
Проблема решается указанием ключа для самого баннера. Тогда при смене слайда старый будет просто выкидываться и не будет ничего ломать:
<BannerContent key={currentSlide} currentSlide={currentSlide} />


А у <motion.x /> ключи можно вообще убрать, без них песочница не ломается.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@karminski
Senior React.JS Developer
Используйте библиотеку uuid для генерации уникальных айдишников. В key должны быть уникальные значения, а всякие там title очевидно могут повторяться.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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