首页 > 解决方案 > React Spring - 动画列表 - 一次列表中的一项

问题描述

给定一个列表:

li {
  display: inline-block;
  color: #000000;
}

<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
</ul>

使用 react-spring,我试图每 3 秒为列表中每个项目的颜色设置动画(一个一个),并从头到尾循环。

例如:

  1. 从 - 颜色开始为黑色
  2. Enter - 颜色变为红色
  3. 离开 - 颜色变回黑色

我可以让单个项目显示和颜色更新然后隐藏(因为列表中只有 1 个项目正在动画),但不是整个列表显示和更改每个项目的颜色 1 到 1。

const ColourListTransition = (items, delay) => {
  const [index, setIndex ] = useState(0);
  useEffect(() => {
    const interval = setInterval(() => {
      setIndex((state) => ( state + 1 ) % items.length);
    }, delay);

    return () => clearInterval(interval);
  }, []);

  return useTransition(items[index], {
    from: { color: '#000000' },
    enter: { color: "#FF0000" },
    leave: { color: "#000000" },
    loop: true,
    config: config.molasses
  })
}

{ ColourListTransition(['item 1', 'item 2', 'item 3', 'item 4'], 3000)(({ color }, item) => (
  <animated.li
    key={ item }
    style={ { color, display: 'inline-block', listStyleType: 'none' } }
  >
    { item }
  </animated.li>
)) }

标签: reactjsreact-spring

解决方案


我玩过,useTransition但我就是想不通。当我改用使用时,这很容易useSprings。所以这可能不是最优雅的解决方案,但它确实有效。

我们创建了一组与您列表中的项目相对应的弹簧动画。每个项目的颜色取决于其索引是否与状态中的活动索引匹配。 enter并且leave在这里并没有真正发挥作用,因为您的数组中总是有相同的 4 个项目。我保持你的useStateuseEffect钩子一样。

import React, { useState, useEffect } from "react";
import { animated, config, useSprings } from "@react-spring/web";

const ColourListTransition = ({delay, items, activeColor, inactiveColor}) => {
  const [index, setIndex] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setIndex((state) => (state + 1) % items.length);
    }, delay);

    return () => clearInterval(interval);
  }, []);

  const [springs] = useSprings(
    // count
    items.length,
    // properties as a function of index
    (i) => ({
      // determine the current color based on the index
      color: i === index ? activeColor : inactiveColor,
      // all items start out black
      from: { color: inactiveColor },
      config: config.molasses
    }),
    // dependency on index state
    [index]
  );

  return (
    <ul>
      {springs.map(({ color }, i) => (
        <animated.li
          key={items[i]}
          style={{ color, display: "inline-block", listStyleType: "none" }}
        >
          {items[i]}
        </animated.li>
      ))}
    </ul>
  );
};

export default function App() {
  return (
    <ColourListTransition
      items={["item 1", "item 2", "item 3", "item 4"]}
      delay={3000}
      activeColor={"#FF0000"}
      inactiveColor={"#000000"}
    />
  );
}

代码沙盒链接


推荐阅读