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

React状态异常:鼠标事件无法正确添加/删除'opacity'元素求助

React状态管理问题:鼠标移出无法删除添加的'opacity'元素

问题根源

  1. 直接操作普通变量而非React状态:你修改的是组件内部的普通变量menuItems,而非通过setItem更新React状态。React依赖状态变更触发重新渲染,直接修改普通变量不会触发状态更新,后续的setItem([...item])使用的还是旧状态值。
  2. 重置状态时使用旧值:restart函数中,你给menuItems重新赋值后,调用setItem([...item]),这里的item仍是修改前的旧状态,导致状态未被正确重置。
  3. 使用数组索引作为key:当数组插入新元素后,后续元素的索引会变化,React无法正确识别元素身份,导致渲染异常。

修正后的代码

import { useState } from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faCancel } from '@fortawesome/free-solid-svg-icons'

// 定义初始菜单数据,给每个项添加唯一ID(避免用索引当key)
const initialMenuItems = [
  { id: 'tasks', name: 'Tasks' },
  { id: 'issues', name: 'Issues' },
  { id: 'files', name: 'Files' },
  { id: 'raports', name: 'Raports' }
]

const Dashboard = ({ slide, tasks, descriptionTasks }) => {
  const [items, setItems] = useState(initialMenuItems)

  const handleSpace = (itemId) => {
    // 基于当前状态创建新数组副本
    const newItems = [...items]
    // 找到目标项的索引
    const targetIndex = newItems.findIndex(item => item.id === itemId)
    // 插入opacity项,给它一个唯一ID避免key冲突
    newItems.splice(targetIndex, 0, { id: `opacity-${Date.now()}`, name: 'opacity' })
    // 更新状态
    setItems(newItems)
  }

  const restart = () => {
    // 直接重置为初始状态数组
    setItems(initialMenuItems)
  }

  return (
    <>
      <div className="dashboard" style={slide.flag ? { left: '-105%' } : { left: '0%' }}>
        <div className="dashboard__nav">
          <ul className="dashboard__nav-list">
            {items.map((menuItem) => (
              <li
                className="dashboard__nav-item"
                key={menuItem.id} // 使用唯一ID作为key
                onMouseOver={() => handleSpace(menuItem.id)}
                onMouseLeave={restart}
              >
                {menuItem.name}
              </li>
            ))}
          </ul>
        </div>
        <div className="dashboard__array">
          {tasks.map((task, id) => (
            <div className="dashboard__array-item" key={id}>
              <div className="dashboard__array-item-header">
                <p className="dashboard__array-item-header-title">{task}</p>
                <button className="dashboard__array-item-header-cancel">
                  <FontAwesomeIcon icon={faCancel} />
                </button>
              </div>
              <div className="dashboard__array-item-main">
                <p className="dashboard__array-item-main-description">{descriptionTasks[id]}</p>
                <p className="dashboard__array-item-main-button">Show More</p>
              </div>
            </div>
          ))}
        </div>
      </div>
    </>
  )
}

export default Dashboard

关键修改说明

  • 状态更新规范:所有数组操作都基于当前状态的副本进行,修改后通过setItems更新状态,确保React能捕获到状态变化并重新渲染。
  • 唯一key:给每个菜单项分配唯一ID,避免使用索引作为key,解决元素识别异常问题。
  • 直接重置状态:restart函数直接将状态设置为初始数组,确保状态被正确重置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 08:40:41