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

如何在React中删除JSX元素列表里被点击的指定元素

核心问题

你现有代码的核心问题是直接将JSX元素存在state中,依赖React内部的key属性做删除判断,这种写法不符合React数据驱动的设计规范,key是React内部用于虚拟DOM diff的属性,不建议业务逻辑直接读取使用。
正确的实现思路是state仅存储渲染需要的源数据,删除时操作源数据,再根据最新的源数据渲染视图即可。


改造后的代码

子组件 InputComponent

const InputComponent = (props) => {
    return ( 
        <div className="input-container">
            <input className="input-name" type="text" />
            <input className="input-value" type="text" />
            <button className="remove-button" onClick={() => props.remove(props.id)}>
                <img src={minusIcon} alt="remove-icon" />
            </button>
        </div>
     );
}
export default InputComponent;

父组件 Main

const Main = () => {
    // state仅存储输入项的源数据,示例用id标识唯一项,后续可扩展存储输入框的name、value等字段
    const [currentInput, setCurrentInput] = useState([{id: 0}]);
    const [newInput, setNewInput] = useState([]);
    const [currentKey, setCurrentKey] = useState(1);
    const [newKey, setNewKey] = useState(0);
    const [currentPlanName, setCurrentPlanName] = useState('Current-Plan');
    const [newPlanName, setNewPlanName] = useState('New-Plan');

    // 接收子组件传递的id,删除对应项
    const handleCurrentRemoval = (id) => {
        setCurrentInput(prev => prev.filter(item => item.id !== id));
    }

    const handleCurrentClick = () => {
        setCurrentInput(prev => [...prev, {id: currentKey}]);
        setCurrentKey(prev => prev + 1);
    };

    // new plan对应的删除、新增逻辑和上述逻辑一致
    const handleNewRemoval = (id) => {
        setNewInput(prev => prev.filter(item => item.id !== id));
    }

    const handleNewClick = () => {
        setNewInput(prev => [...prev, {id: newKey}]);
        setNewKey(prev => prev + 1);
    };

    return ( 
        <div className="main-container">
            <div className="quote-container">
                <div className="current-plan">
                    <h2>{currentPlanName}</h2>
                    {/* 遍历源数据生成对应的JSX元素 */}
                    {currentInput.map((item) => (
                        <InputComponent 
                            key={item.id} 
                            id={item.id} 
                            remove={handleCurrentRemoval} 
                        />
                    ))}
                    <div className="button-container">
                        <button className="add-input" onClick={handleCurrentClick}>
                            <img src={addIcon} alt="add"/>
                        </button>
                    </div>
                </div>
                <div className="new-plan">
                    <h2>{newPlanName}</h2>
                    {newInput.map((item) => (
                        <InputComponent 
                            key={item.id} 
                            id={item.id} 
                            remove={handleNewRemoval} 
                        />
                    ))}
                    <div className="button-container">
                        <button className="add-input" onClick={handleNewClick}>
                            <img src={addIcon} alt="add"/>
                        </button>
                    </div>
                </div>
            </div>
        </div>
     );
}
export default Main;

逻辑说明

  • 子组件点击删除按钮时,将自身的唯一id传递给父组件的删除回调
  • 父组件的删除方法根据传入的id过滤源数据,更新state
  • state更新后React会自动根据最新的源数据重新渲染视图,对应id的子组件就会被移除
  • 后续如果需要获取输入框的填写内容,只需要在state的源数据中扩展name、value字段,给InputComponent添加onChange回调同步值到父组件即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 20:27:00