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

Inertia/React中useForm删除后tr元素动画异常问题

问题分析与解决方案

问题根源

你直接操作DOM元素的方式和React的声明式渲染机制冲突了:

  • 调用setMessage会触发组件重新渲染,此时React会根据删除后的users数据重新生成表格DOM
  • 你提前保存的tr引用指向的是旧DOM节点,组件重新渲染后这个节点已经被React替换,导致动画错误地应用到了新渲染出的下一行上

修复方案

改用React状态管理来标记要删除的行,让React控制动画类的添加和DOM更新:

  1. 添加状态标记要删除的用户ID
const UsersContent = ({ users, flash }) => {
    const { delete: formDelete } = useForm();
    const [message, setMessage] = useState(flash.message);
    // 添加状态:记录正在删除的用户ID
    const [deletingUserId, setDeletingUserId] = useState(null);

    // 原有的useEffect代码不变
    useEffect(() => {
        const timer = setTimeout(() => {
            setMessage(null);
        }, 3000);

        return () => clearTimeout(timer);
    }, [message]);

    const handleSubmit = (e) => {
        e.preventDefault();
        const userId = e.target.id;
        
        formDelete(route('users.destroy', userId), {
            onSuccess: () => {
                // 标记当前要删除的用户,由React给对应tr加动画类
                setDeletingUserId(userId);
                setMessage({ tipo: 'success', testo: `Utente ${userId} cancellato correttamente` });

                // 动画结束后,重置标记(如果Inertia未自动刷新数据,可手动过滤本地users)
                setTimeout(() => {
                    setDeletingUserId(null);
                    // 若users是本地状态,可手动移除:
                    // setUsers(prev => prev.filter(u => u.id !== userId));
                }, 2000);
            },
            onError: () => {
                setMessage({ tipo: 'danger', testo: `Errore durante la cancellazione dell'utente ${userId}` });
            }
        });
    }

    // 渲染表格时根据状态添加动画类
    return (
        <table>
            <tbody>
                {users.map(user => (
                    <tr
                        key={user.id}
                        className={deletingUserId === user.id ? 'fadeout' : ''}
                    >
                        {/* 表格内容 */}
                        <td>
                            <form onSubmit={handleSubmit} id={user.id}>
                                <button type="submit">删除</button>
                            </form>
                        </td>
                    </tr>
                ))}
            </tbody>
        </table>
    );
}
  1. 关键说明
  • 利用React的状态驱动渲染,让tr的fadeout类由deletingUserId状态控制,避免直接操作DOM
  • 动画结束后,要么等待Inertia自动刷新页面props(删除后的users数据),要么手动过滤本地users状态(如果是本地维护的)
  • 确保每个tr都有唯一的key(用user.id),让React能准确识别DOM节点,避免渲染混乱

为什么原代码失效?

React是声明式框架,组件渲染完全依赖状态/ props。当你调用setMessage更新状态时,组件会重新渲染,此时原来的tr DOM节点已经被React销毁并替换为新的DOM结构,你之前保存的tr引用已经无效,导致动画被错误地应用到了新的DOM节点上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 12:41:03