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

如何在React中实现Semantic UI卡片的编辑与删除功能

嘿,刚从jQuery转React确实需要适应一下思路的转变,不过别担心,我来一步步帮你把需求落地,顺便理清楚两者的核心差异和转换步骤~

核心思路先转变:从jQuery到React的本质区别

你用jQuery的时候习惯直接操作DOM(比如选元素、改内容、加动画),但React是状态驱动DOM——所有界面变化都由状态(state)控制,你只需要修改状态,React会自动帮你更新对应的DOM,不用手动去操作元素。这是最关键的一点,得先把这个思路转过来。

步骤1:把卡片数据放进React状态里

你现在用的sampleUsers应该是静态数据,首先要把它放到组件的状态中,这样才能实现编辑、删除后的数据更新。用React的useState钩子就能搞定:

import { useState } from 'react';

function UserCards() {
  // 把静态数据存入state,users是当前数据,setUsers是修改数据的方法
  const [users, setUsers] = useState(sampleUsers);

  // 后续的编辑、删除逻辑都在这里写
  return (
    <div className="ui cards">
      {/* 这里我们之后换成子组件渲染 */}
      {users.map(user => (
        <UserCard key={user.id} user={user} />
      ))}
    </div>
  );
}

注意:每个循环渲染的元素必须加key,这里用用户的id是最优选择,能帮React高效更新DOM。

步骤2:实现卡片编辑功能

编辑功能需要让卡片在“查看模式”和“编辑模式”之间切换,我们可以把单个卡片抽成一个子组件UserCard,让它自己管理编辑状态:

function UserCard({ user, onUpdate }) {
  // 局部状态:控制是否处于编辑模式
  const [isEditing, setIsEditing] = useState(false);
  // 存编辑中的数据,初始值用传入的user数据
  const [editedName, setEditedName] = useState(user.name);
  const [editedEmail, setEditedEmail] = useState(user.email);

  // 保存编辑的方法:把修改后的数据传给父组件更新state
  const handleSave = () => {
    onUpdate(user.id, { name: editedName, email: editedEmail });
    setIsEditing(false); // 切回查看模式
  };

  return (
    <div className="ui card">
      {isEditing ? (
        {/* 编辑模式:显示输入框 */}
        <div className="content">
          <div className="header">
            <input 
              type="text" 
              value={editedName}
              onChange={(e) => setEditedName(e.target.value)}
              className="ui input"
            />
          </div>
          <div className="description">
            <input 
              type="email" 
              value={editedEmail}
              onChange={(e) => setEditedEmail(e.target.value)}
              className="ui input"
            />
          </div>
        </div>
        <div className="extra content">
          <button className="ui green button" onClick={handleSave}>保存</button>
          <button className="ui grey button" onClick={() => setIsEditing(false)}>取消</button>
        </div>
      ) : (
        {/* 查看模式:显示文本 */}
        <div className="content">
          <div className="header">{user.name}</div>
          <div className="description">{user.email}</div>
        </div>
        <div className="extra content">
          <button className="ui blue button" onClick={() => setIsEditing(true)}>编辑</button>
          {/* 先留个位置放删除按钮,后面实现 */}
        </div>
      )}
    </div>
  );
}

然后在父组件里实现onUpdate方法,用来更新全局的用户数据:

function UserCards() {
  const [users, setUsers] = useState(sampleUsers);

  const handleUpdateUser = (userId, updatedData) => {
    // 用map更新对应id的用户数据,返回新数组(React要求不能直接修改原state)
    setUsers(users.map(user => 
      user.id === userId ? { ...user, ...updatedData } : user
    ));
  };

  return (
    <div className="ui cards">
      {users.map(user => (
        <UserCard 
          key={user.id} 
          user={user} 
          onUpdate={handleUpdateUser} 
        />
      ))}
    </div>
  );
}
步骤3:实现带动画的删除功能(模拟jQuery效果)

jQuery里删除卡片通常是先做淡出动画,再移除元素。React里我们可以用状态控制CSS类来实现动画,等动画结束后再从state里删掉对应数据:

首先修改UserCard组件,添加删除状态和动画逻辑:

function UserCard({ user, onUpdate, onDelete }) {
  const [isEditing, setIsEditing] = useState(false);
  // 新增:控制是否处于删除动画状态
  const [isDeleting, setIsDeleting] = useState(false);
  const [editedName, setEditedName] = useState(user.name);
  const [editedEmail, setEditedEmail] = useState(user.email);

  const handleSave = () => {
    onUpdate(user.id, { name: editedName, email: editedEmail });
    setIsEditing(false);
  };

  // 点击删除按钮时,先触发动画
  const handleDeleteClick = () => {
    setIsDeleting(true);
  };

  // 动画结束后,通知父组件删除该用户
  const handleAnimationEnd = () => {
    if (isDeleting) {
      onDelete(user.id);
    }
  };

  return (
    {/* 通过isDeleting状态添加Semantic UI的淡出动画类 */}
    <div 
      className={`ui card ${isDeleting ? 'fade out' : ''}`}
      onAnimationEnd={handleAnimationEnd}
    >
      {/* 原有编辑/查看内容不变 */}
      {isEditing ? (
        <>
          <div className="content">
            <div className="header">
              <input 
                type="text" 
                value={editedName}
                onChange={(e) => setEditedName(e.target.value)}
                className="ui input"
              />
            </div>
            <div className="description">
              <input 
                type="email" 
                value={editedEmail}
                onChange={(e) => setEditedEmail(e.target.value)}
                className="ui input"
              />
            </div>
          </div>
          <div className="extra content">
            <button className="ui green button" onClick={handleSave}>保存</button>
            <button className="ui grey button" onClick={() => setIsEditing(false)}>取消</button>
          </div>
        </>
      ) : (
        <>
          <div className="content">
            <div className="header">{user.name}</div>
            <div className="description">{user.email}</div>
          </div>
          <div className="extra content">
            <button className="ui blue button" onClick={() => setIsEditing(true)}>编辑</button>
            <button className="ui red button" onClick={handleDeleteClick}>删除</button>
          </div>
        </>
      )}
    </div>
  );
}

然后在父组件里实现onDelete方法:

function UserCards() {
  const [users, setUsers] = useState(sampleUsers);

  const handleUpdateUser = (userId, updatedData) => {
    setUsers(users.map(user => 
      user.id === userId ? { ...user, ...updatedData } : user
    ));
  };

  // 删除用户:过滤掉对应id的用户,返回新数组
  const handleDeleteUser = (userId) => {
    setUsers(users.filter(user => user.id !== userId));
  };

  return (
    <div className="ui cards">
      {users.map(user => (
        <UserCard 
          key={user.id} 
          user={user} 
          onUpdate={handleUpdateUser} 
          onDelete={handleDeleteUser}
        />
      ))}
    </div>
  );
}

这里用到了Semantic UI自带的fade out动画类,如果你需要其他动画效果,比如收缩,也可以用Semantic UI的其他动画类,或者自定义CSS动画~

从jQuery到React的转换步骤总结

给你提炼几个关键步骤,以后遇到类似转换也能用:

  • 1. 从“操作DOM”转向“状态驱动”:把所有需要修改的内容都放进React的state里,不要再用$('.element').text()这种方式改内容,而是修改state让React自动更新。
  • 2. 拆分可复用组件:把重复的DOM结构(比如单个卡片)抽成子组件,每个组件管理自己的局部状态(比如编辑、动画状态),共享数据放在父组件里。
  • 3. 事件处理从“DOM绑定”到“props传递”:原来用$('.btn').click()绑定事件,现在直接在React元素上写onClick,通过props把父组件的处理函数传给子组件。
  • 4. 动画通过“状态控制类名”实现:不要用jQuery的fadeOut(),而是用状态切换CSS类,监听动画结束事件再更新数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:03:23