You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

react-spring useTransition移除元素后,如何实现下方元素平滑上移动画?

问题描述

使用react-spring为数组元素实现显隐动画时,移除数组中间元素后,下方元素会瞬间跳转至新位置,没有平滑的上移动画效果。

动画效果

解决方法

要实现元素移除后下方元素的平滑上移动画,需从以下三点调整:

  • 给元素分配唯一标识:react-spring需要通过唯一key准确识别每个元素的状态(保留/移除),避免误判元素身份。将数组改为带唯一ID的对象数组,而非纯字符串数组。
  • 启用布局动画:在useTransition配置中添加layout: true,让react-spring自动处理元素位置变化的过渡动画。
  • 调整离开动画:给离开的元素添加高度过渡动画,让元素从原有高度收缩至0,下方元素会随空间变化平滑上移。
修改后的代码
"use client";

import React, { useState } from 'react'
import { animated, useTransition } from "@react-spring/web";

const Test = () => {
  // 改为带唯一ID的对象数组,确保元素身份可被准确跟踪
  const [items, setItems] = useState([
    { id: 1, value: "1" },
    { id: 2, value: "2" },
    { id: 3, value: "3" },
    { id: 4, value: "4" },
    { id: 5, value: "5" },
    { id: 6, value: "6" },
  ]);

  const removeItem = () => {
    if (items.length === 0) return;
    // 移除id为3和4的元素(对应原数组的"3""4")
    const newItems = items.filter(item => item.id !== 3 && item.id !== 4);
    setItems(newItems);
  };

  const transitions = useTransition(items, {
    // 使用元素的唯一ID作为key
    keys: item => item.id,
    from: { opacity: 0, height: 0, transform: "translate3d(0, 100dvh, 0)" },
    enter: { opacity: 1, height: "10dvh", transform: "translate3d(0, 0, 0)" },
    // 离开时同时处理位移、透明度和高度收缩
    leave: { opacity: 0, height: 0, transform: "translate3d(200dvw, 0, 0)" },
    trail: 50,
    config: { duration: 1000 },
    // 启用布局动画,处理元素位置变化的过渡
    layout: true
  });

  return (
    <div>
      <div>
        <button onClick={removeItem}>Remove Item</button>
      </div>
      <div style={{ gap: "8px" }}>
        {transitions((style, item) => (
          <animated.div style={style}>
            <div style={{
              width: "100%",
              height: "100%",
              display: "flex",
              justifyContent: "center",
              alignItems: "center",
              color: "white",
              fontSize: "20px",
              backgroundColor: "red"
            }}>
              {item.value}
            </div>
          </animated.div>
        ))}
      </div>
    </div>
  );
}

export default Test;
关键改动说明
  • 用带id的对象数组替代纯字符串数组,通过keys: item => item.id让react-spring精准跟踪每个元素的状态,避免元素被误判为新创建或已删除。
  • 添加layout: true开启布局动画,让元素位置变化时自动生成平滑过渡效果。
  • 在动画配置中加入height属性的过渡:进入时从0变为10dvh,离开时从10dvh变为0,让下方元素随空间收缩自然上移,消除瞬间跳转的问题。
  • 调整动画时长为1000ms,让整体过渡节奏更协调(可根据需求修改)。

内容的提问来源于stack exchange,提问作者SageJustus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 20:35:05