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

React中LocalStorage未更新导致卡片删除异常问题求助

React卡片删除后重复显示的问题

这是我的card.js文件:

import React, { useState, useEffect } from 'react'
// import { PdtList } from './Cart';
export default function Card(props) {
    let list = JSON.parse(localStorage.getItem("context"))
    const [setstyle, setsetstyle] = useState({
        color: 'black',
        background: 'rgb(238, 242, 241)'
    })
    const DeleteItem = (e) => {
        console.log("to be deleted -> ", e);
        setsetstyle({
            display: 'none'
        })
        var filteredArray = list.filter(x => x.id !== e);
        localStorage.setItem('context', JSON.stringify(filteredArray));
        list = filteredArray;
    }
    
    const { id, images, name } = props;
    return (
        <div id={id} className='align displaySet' style={setstyle} >
            <main>
                <div className="border align">
                    <img src={images} alt="" />
                    <h3>{name}</h3>
                </div>
            </main>
            <button onClick={() => DeleteItem(id)} >Delete</button>
        </div>
    )
}

问题表现

点击Delete Button时,首次可删除一张卡片,但点击另一张卡片时,当前点击的卡片被移除后,之前删除的卡片又重新显示出来。

问题根源

你推测的方向完全正确,核心问题有两个:

  • 每次组件渲染时,let list = JSON.parse(localStorage.getItem("context"))都会重新从localStorage读取数据,覆盖你修改后的list变量,导致状态不一致
  • 用setstyle隐藏卡片只是视觉层面的临时处理,并没有真正从组件列表中移除,当其他卡片触发重新渲染时,所有Card组件都会重新读取localStorage数据,已隐藏的卡片会重新显示

解决方案

方案1:状态提升到父组件(推荐)

React中共享数据的状态应该放在父组件统一管理,子组件只负责渲染和触发操作,这是最佳实践:

父组件示例(Cart.js)

import React, { useState, useEffect } from 'react'
import Card from './Card'

export default function Cart() {
    // 父组件维护列表的响应式状态
    const [itemList, setItemList] = useState([])

    // 初始化时从localStorage加载数据
    useEffect(() => {
        const savedList = JSON.parse(localStorage.getItem("context")) || []
        setItemList(savedList)
    }, [])

    // 统一处理删除逻辑
    const handleDelete = (id) => {
        const filteredArray = itemList.filter(x => x.id !== id)
        setItemList(filteredArray)
        localStorage.setItem('context', JSON.stringify(filteredArray))
    }

    return (
        <div className="cart-container">
            {/* 遍历列表渲染Card,传递数据和删除方法 */}
            {itemList.map(item => (
                <Card 
                    key={item.id}
                    id={item.id}
                    images={item.images}
                    name={item.name}
                    onDelete={handleDelete}
                />
            ))}
        </div>
    )
}

修改后的Card.js

import React from 'react'

export default function Card(props) {
    const { id, images, name, onDelete } = props;

    return (
        <div id={id} className='align displaySet' >
            <main>
                <div className="border align">
                    <img src={images} alt="" />
                    <h3>{name}</h3>
                </div>
            </main>
            <button onClick={() => onDelete(id)} >Delete</button>
        </div>
    )
}

方案2:在Card组件内修复(临时方案)

如果暂时不想调整组件结构,需要把list改成响应式状态,并用条件渲染替代样式隐藏:

import React, { useState, useEffect } from 'react'

export default function Card(props) {
    // 用useState维护响应式列表状态
    const [list, setList] = useState([])
    const { id, images, name } = props;

    // 初始化加载localStorage数据
    useEffect(() => {
        const savedList = JSON.parse(localStorage.getItem("context")) || []
        setList(savedList)
    }, [])

    const DeleteItem = (deleteId) => {
        const filteredArray = list.filter(x => x.id !== deleteId)
        setList(filteredArray)
        localStorage.setItem('context', JSON.stringify(filteredArray))
    }

    // 只有当前卡片id存在于列表中时才渲染
    if (!list.some(item => item.id === id)) {
        return null
    }

    return (
        <div id={id} className='align displaySet' >
            <main>
                <div className="border align">
                    <img src={images} alt="" />
                    <h3>{name}</h3>
                </div>
            </main>
            <button onClick={() => DeleteItem(id)} >Delete</button>
        </div>
    )
}

关键提示

  • 状态提升能从根本上避免多组件共享数据的状态不一致问题
  • 不要用修改样式的方式隐藏组件,应该通过条件渲染真正移除组件
  • 只有React的响应式状态(useState/useReducer)才能触发组件重新渲染,普通变量修改不会被React感知

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 06:10:31