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
相关产品推荐
相关产品推荐

