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

React中向DOM添加元素需两次点击而非一次的问题如何解决?

问题原因
  1. 事件冒泡:添加按钮位于绑定了点击事件的.utility父容器内部,点击按钮时事件会向上冒泡触发父容器的showIcon回调,单次点击同时执行两个逻辑,导致状态更新异常,表现为需要点击两次才能生效。
  2. 不合理的State用法:直接将React组件实例存储在State中,不符合React设计规范,容易触发闭包陷阱,导致回调函数获取到旧的状态值。
修复方案
  • 点击添加按钮时调用e.stopPropagation()阻止事件冒泡,避免触发父容器的点击回调
  • 调整State结构,使用布尔值控制添加按钮的显隐,不要在State中存储JSX元素
  • 更新列表状态时使用函数式写法,避免闭包导致的旧状态依赖问题
修正后代码
import React, {useState} from 'react'
import StabelItem from './StabelItem';

import { library } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faPlusCircle} from '@fortawesome/free-solid-svg-icons';

library.add(faPlusCircle)

// React组件名需首字母大写
function AddItems() {
    // 用布尔值控制图标显隐
    const [showAddIcon, setShowAddIcon] = useState(false);
    const [stabelItem, setStabelItem] = useState({items:[]});
    
    const showIcon = ()=> {
        setShowAddIcon(true)
    }

    const addStabelItem = (e) => {
        // 阻止事件冒泡
        e.stopPropagation();
        // 函数式更新避免闭包问题
        setStabelItem(prev => ({items: [...prev.items, <StabelItem />]}))
    }

    return (
        <div className="utility" onClick={showIcon}>
        <li className="box-item" >
        <div className="flexrow" >
            <div className='number norest'>Total</div>
            <div className='number calc margin-left norest'>0</div>
        </div>
        <ul className="movements">
        {stabelItem.items}
        {/* 条件渲染图标 */}
        {showAddIcon && <FontAwesomeIcon onClick={addStabelItem} icon={["fas", "plus-circle"]}/>}
        </ul>
    </li>
</div>
    )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 18:30:02