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

如何基于React State数组实现任务状态切换的下落动画?

实现React任务项下落动画的可用库

你需要的是列表项位置变化时的平滑过渡动画,以下几个主流库可以解决这个问题,结合你的任务排序场景给出具体用法:

1. React Transition Group(官方替代方案)

这是ReactCSSTransition废弃后官方推荐的库,其中TransitionGroup组件专门处理列表元素的增删、排序动画。

核心用法示例:

import { TransitionGroup, CSSTransition } from 'react-transition-group';

// 点击标记任务完成并重新排序
const handleTaskComplete = (taskId) => {
  setTasks(prevTasks => {
    // 更新当前任务的completed状态
    const updatedTasks = prevTasks.map(task => 
      task.id === taskId ? { ...task, completed: true } : task
    );
    // 重新排序:未完成在前,已完成在后
    return [...updatedTasks.filter(t => !t.completed), ...updatedTasks.filter(t => t.completed)];
  });
};

// 渲染部分
<div>
  <TransitionGroup>
    {tasks.map((elem) => (
      <CSSTransition key={elem.id} timeout={500} classNames="fall">
        <div onClick={() => handleTaskComplete(elem.id)}>
          {elem.name}
        </div>
      </CSSTransition>
    ))}
  </TransitionGroup>
</div>

对应的CSS动画:

/* 进入/退出初始状态 */
.fall-enter, .fall-exit {
  transform: translateY(0);
  opacity: 1;
}

/* 动画执行状态 */
.fall-enter-active, .fall-exit-active {
  transform: translateY(100%);
  opacity: 0.8;
  transition: transform 500ms ease-in-out, opacity 500ms ease;
}

2. Framer Motion

目前最流行的React动画库,API简洁,支持自动识别列表元素位置变化并生成过渡动画。

核心用法示例:

import { motion } from 'framer-motion';

// 点击处理逻辑同前
const handleTaskComplete = (taskId) => {
  setTasks(prevTasks => {
    const updatedTasks = prevTasks.map(task => 
      task.id === taskId ? { ...task, completed: true } : task
    );
    return [...updatedTasks.filter(t => !t.completed), ...updatedTasks.filter(t => t.completed)];
  });
};

// 渲染部分
<div>
  {tasks.map((elem) => (
    <motion.div
      key={elem.id}
      layout // 自动处理位置变化的过渡动画
      transition={{ type: "spring", stiffness: 300, damping: 30 }}
      onClick={() => handleTaskComplete(elem.id)}
    >
      {elem.name}
    </motion.div>
  ))}
</div>

只需给元素添加layout属性,Framer Motion会自动计算位置差并生成自然的下落动画,无需手动编写复杂CSS。

3. React Spring

基于物理引擎的动画库,适合追求自然动效的场景,对列表排序动画支持完善。

核心用法示例:

import { useTransition, animated } from 'react-spring';

// 定义过渡动画规则
const transitions = useTransition(tasks, {
  key: task => task.id,
  from: { transform: 'translateY(0)', opacity: 1 },
  update: { transform: 'translateY(0)', opacity: 1 },
  leave: { transform: 'translateY(100%)', opacity: 0.6 },
  config: { tension: 200, friction: 20 }
});

// 渲染部分
<div>
  {transitions((style, item) => (
    <animated.div 
      style={style} 
      onClick={() => handleTaskComplete(item.id)}
    >
      {item.name}
    </animated.div>
  ))}
</div>

通过useTransition可以精准控制元素进入、更新、离开时的动画状态,物理参数配置能让下落动效更贴合真实世界的运动规律。

关键注意事项

  • 必须给每个列表项设置唯一的key(不要用数组索引),否则动画库无法正确识别元素的变化。
  • 排序逻辑要确保生成新的数组(而非修改原数组),触发组件重渲染后,动画库才能捕获到元素位置的变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 10:10:00