每个子组件的独立状态与useSelector挂钩

时间:2020-11-08 21:38:32

标签: reactjs react-redux react-hooks redux-toolkit

我有一个加载图像的应用程序,我想单击一个“赞”图标,然后单击图像,或者单击一个垃圾桶图标以删除图像。在对后端的呼叫尚待处理时,我想显示一个微调框而不是图标。从商店中获取呼叫的加载状态时,我所有的组件都会同时更新,而不仅仅是定位我正在点击的当前组件

看起来像这样(单击“赞”按钮后将显示旋转框)

enter image description here

您会看到微调框出现在每个ImageCard上!!!

ImageCard.tsx

export function ImageCard({ image }: ImageProp): ReactElement {
    const [liked, setLiked] = useState(image.tags.includes(TAGS.FAV));
    const imageLikeState = useSelector(likeImagePending);
    const imageDeleteState = useSelector(deleteImagePending);

    const dispatch = useDispatch();
    const like = (public_id: string, tag: string) => {
        setLiked(!liked);
        dispatch(toggleLiked(public_id, tag));
    };
    const deleteImage = (public_id: string) => {
        dispatch(deleteImageCall(public_id));
    };

    return (
        <div className="card mb-5 portfolio-item">
            <div className="card-image">
                <img className="image" src={image.secure_url} alt="" />
            </div>
            <div className="card-button-container">
                {!imageDeleteState && (
                    <FontAwesomeIcon
                        onClick={() => deleteImage(image.public_id)}
                        icon={trashRegular}
                        size="lg"
                        color="#FF4545"
                    />
                )}

                {imageDeleteState && <img className="spinner" src={Spinner} alt="Loading Spinner" />}

                <div className="rating-container">
                    <FontAwesomeIcon icon={starRegular} size="lg" color="#FF9529" />
                    <FontAwesomeIcon icon={starRegular} size="lg" color="#FF9529" />
                    <FontAwesomeIcon icon={starRegular} size="lg" color="#FF9529" />
                    <FontAwesomeIcon icon={starRegular} size="lg" color="#FF9529" />
                    <FontAwesomeIcon icon={starRegular} size="lg" color="#FF9529" />
                </div>

                {!imageLikeState && (
                    <FontAwesomeIcon
                        onClick={() => like(image.public_id, TAGS.FAV)}
                        icon={liked ? heartSolid : heartOutline}
                        size="lg"
                        color="#1A8CC9"
                    />
                )}

                {imageLikeState && <img className="spinner" src={Spinner} alt="Loading Spinner" />}
            </div>
        </div>
    );
}

1 个答案:

答案 0 :(得分:1)

const imageLikeState = useSelector(likeImagePending);
const imageDeleteState = useSelector(deleteImagePending);

基于此,您似乎有一个选择器,该选择器告诉您任何图片是否正在处理。您想要的是一个选择器,它可以告诉您特定的图片ID是否待处理。

组件代码应如下所示

const imageLikeState = useSelector(likeImagePending(image.public_id));
const imageDeleteState = useSelector(deleteImagePending(image.public_id));

这意味着您需要更改选择器以及可能的redux状态。如果您当前正在存储boolean的{​​{1}}值,则一种简单的解决方案是对其进行更改,以使在您的redux状态下存储的值是待处理图像的数字ID,即{{1 }}(如果没有)。

您的选择器将检查您在参数中传递的ID是否与待处理的ID相匹配,并返回isLikePending

false