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

为点击筛选按钮的筛选项添加动画效果(修复异常问题)

问题排查与解决方案

问题根源

  1. 动画状态逻辑错误:当前用anim布尔值翻转来控制动画类,每次点击按钮都会切换状态——第一次点击添加动画类,第二次点击移除,导致出现「有动画→无内容→有动画」的交替现象(推测你的CSS中fil-item默认隐藏,仅fil-item-active才显示并执行动画)。
  2. 状态不同步:筛选数据和动画状态的更新没有配合,动画触发逻辑依赖手动翻转状态,而非数据变化的时机。

修复方案

我们需要每次筛选数据变化时强制触发一次完整的动画流程,而非简单切换布尔状态。以下是修改后的代码:

import React, { useState, useEffect } from 'react';
import suggestData from '../data/suggest-data.json';

const allCategories = ['All', ...new Set(suggestData.map(item => item.area))];

const Suggest = () => {
    const [suggestItem, setSuggestItem] = useState(suggestData);
    const [selectedIndex, setSelectedIndex] = useState(0);
    const [isAnimating, setIsAnimating] = useState(false);

    const filter = (button) => {
        let filteredData = suggestData;
        if (button !== 'All') {
            filteredData = suggestData.filter(item => item.area === button);
        }
        setSuggestItem(filteredData);
    }

    // 监听筛选数据变化,自动触发动画
    useEffect(() => {
        // 触发动画:添加动画类
        setIsAnimating(true);
        // 动画结束后移除类(时长需和你的CSS动画时长匹配)
        const timer = setTimeout(() => {
            setIsAnimating(false);
        }, 500);
        return () => clearTimeout(timer);
    }, [suggestItem]);

    return (
        <div>
            <h1>Suggest</h1>
            <div className="fil">
                <div className="fil-btns">
                    <div className="fil-btn">
                        <button className='btn'>Hello</button>
                        {allCategories.map((cat, index) => (
                            <button
                                type="button"
                                key={index}
                                onClick={() => {
                                    filter(cat);
                                    setSelectedIndex(index);
                                }}
                                className={`btn ${selectedIndex === index ? "btn-active" : ""}`}
                            >
                                {cat}
                            </button>
                        ))}
                    </div>
                </div>
                <div className="fil-items">
                    {suggestItem.map((item, index) => (
                        <div
                            className={`fil-item ${isAnimating ? "fil-item-active" : ""}`}
                            key={item.id || index} {/* 优先用数据唯一ID作为key,避免DOM复用问题 */}
                        >
                            <h1>{item.name}</h1>
                            <h2>{item.category}</h2>
                            <h3>{item.location}</h3>
                            <h4>{item.type}</h4>
                            <h5>{item.area}</h5>
                        </div>
                    ))}
                </div>
            </div>
        </div>
    );
}

export default Suggest;

额外优化说明

  • 移除了无用的butto状态,直接用allCategories渲染按钮,简化代码。
  • 优化filter函数逻辑,减少分支判断。
  • 建议用数据的唯一标识(如item.id)代替index作为列表key,避免React列表渲染时的DOM复用问题,确保动画正常触发。
  • 定时器时长需与你的CSS动画时长匹配,示例中假设动画时长为500ms。

参考CSS样式

确保动画类的样式逻辑正确,示例如下:

.fil-item {
    opacity: 0;
    transform: translateY(20px);
    transition: all 0.5s ease;
}
.fil-item-active {
    opacity: 1;
    transform: translateY(0);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 17:24:29