首页 > 解决方案 > 从数组中删除项目并使用正确的数组长度更新子组件

问题描述

我正在尝试在产品列表上实现 LIKE 功能,我有一个 Redux 状态,在每个 Liked 项目上都会将该项目添加到列表中。但是,当我再次单击同一项目时,我希望将该项目从“喜欢”列表中删除。它实际上似乎在我遵循状态时起作用,但在我的 UI 中,我有一个子组件,它保存所有喜欢的项目,它不反映操作。

这是我喜欢的组件:

function LikeProduct (props) {

    const [like, setLike] = useState(false);
    const { product, setLikedProducts, removeLikedProduct } =  props;

    const handleLike = () => {
        return like ? (setLike(false), removeLikedProduct(product)) : (setLike(true), setLikedProducts(product));
    }

    return (
        <div className="LikeProduct">
            <Button 
                className={like ? "LikeProduct__like" : "LikeProduct__button"} 
                variant="link"
                onClick={handleLike}>
                <FaRegThumbsUp />
            </Button>
        </div>
    );
}

该组件被导入到 Card 组件中,如下所示:

<LikeProduct product={product.title} />

它传递了按标题喜欢的产品名称;

我的行动:

export function removeLikedProduct (product) {
    return {
        type: REMOVE_LIKED_PRODUCT,
        product
    }
}

我的减速机:

const setLikedProductReducer = (state=[], action) => {
    switch (action.type) {
        case SET_LIKED_PRODUCT:
            return state.concat(action.product)
        case REMOVE_LIKED_PRODUCT:
            // debugger;
            state.splice(state.indexOf(action.product), 1);
            return state;
        default:
            return state    
    }
}

export default setLikedProductReducer;

现在我有这个 Header 组件,我在其中 mapPropsToSate:

function Header (props) {

    const [list, showList] = useState(false);
    const { liked } = props;

    const handleLikedList = () => {
        showList(true);
    }


    return (
        <div className="Header">
            <Navbar variant="light" bg="light">
                <Navbar.Brand>Troll</Navbar.Brand>

                <Button 
                    className="Header__likedList"
                    variant="link"
                    onClick={handleLikedList}>
                        <FaRegThumbsUp /> 
                        <span>{ liked.length }</span>
                </Button>
                {/* { list ? <div>TROLL</div> : null} */}
            </Navbar>
        </div>
      );
}

问题在这里,<span>{ liked.length }</span>这不反映状态,因此如果我删除 1 个项目,它不会反映在 UI 中,但它确实在 redux 状态下显示该项目已被删除,因此长度始终是最大长度

标签: reactjs

解决方案


首先制作您的初始状态对象 state = {} 。然后每次当你在你的 reducer 中改变状态时,你都必须返回一个新的状态副本。例如,当您将新项目添加到状态中的现有项目时:

return {...state, products: [...state.products, payload]}

当你移除物品时

return {...state, products: state.products.filter(item => item !== payload)}

推荐阅读