当我使用redux和array时,我如何分别返回状态?



我试图通过使用redux和map函数在其他组件中使用状态来实现like函数。我使用redux而不是useState([]),因为我认为它是管理状态的更好方法。当按钮被点击时,我改变了按钮。但是它们共享相同的状态,所以它同时被改变了。为了解决这个问题,我想我应该把这个状态添加到数组中。我的问题来了。如何添加redux中声明的状态来单独管理状态?这种方法正确吗?我将上传具体的代码,包括redux使用codesandbox。如果你能告诉我,我会很感激的,谢谢。

import React, { useState } from "react";
import styled from "styled-components";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faHeart } from "@fortawesome/free-solid-svg-icons";
import { faHome } from "@fortawesome/free-solid-svg-icons";
import { useDispatch, useSelector } from "react-redux";
const array = [
{
id: "1",
name: "vest",
img:
"https://shopimg.kakaofriendsgolf.com/live/images/2022/9/7/10/918997_1662515279620.png",
price: "10000"
},
{
id: "2",
name: "shirts",
img:
"https://shopimg.kakaofriendsgolf.com/live/images/2022/8/23/18/551886_1661246483199.png",
price: "12000"
},
{
id: "3",
name: "pants",
img:
" https://shopimg.kakaofriendsgolf.com/live/images/2022/8/22/18/18783_1661159105201.png",
price: "15000"
}
];
export default function Clothes() {
const isClick = useSelector((state) => state.CheckLike.isClick);
const dispatch = useDispatch();
// change Icon
const setHide = (e) => {
dispatch({ type: "False" });
};
const setShow = (e) => {
dispatch({ type: "True" });
};
return (
<Wrap>
<div className="productCard">
{array.map((content, idx) => {
return (
<div key={idx} className="productCard__wrap">
<img src={content.img} className="productCard__img" />
<div className="productCard__name">
<div>
<h3 className="productCard__title">{content.name}</h3>
<div className="productCard__priceWrap">
{content.price
.toString()
.replace(/B(?=(d{3})+(?!d))/g, ",")}
</div>
</div>
<div className="productCard__likeWrap">
{/* show heart and house icon according to state */}
{isClick ? (
<div
onClick={() => {
setHide();
}}
>
<FontAwesomeIcon icon={faHeart} />
</div>
) : (
<div
onClick={() => {
setShow();
}}
>
<FontAwesomeIcon icon={faHome} />
</div>
)}
</div>
</div>
</div>
);
})}
</div>
</Wrap>
);
}
const Wrap = styled.div`
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow: scroll;
.productCard {
display: flex;
position: absolute;
top: calc(50vh - 120px);
left: calc(50vw - 180px);
width: "228px";
height: "351px";
padding-right: 8px;
padding-left: 8px;
border: solid 1px black;
}
.productCard__wrap {
border: 1px solid grey;
line-height: 1.428571429;
background-color: #fff;
}
.productCard__img {
width: 228px;
height: 228px;
}
.productCard__name {
padding-bottom: 30px;
position: relative;
padding: 8px 8px 0 8px;
min-height: 118px;
text-align: left;
}
.productCard__title {
font-size: 18px;
margin-top: 0;
margin-bottom: 2px;
padding-right: 37px;
line-height: 1.3;
margin-block-start: 1em;
margin-block-end: 1em;
}
.productCard__priceWrap {
font-size: 18px;
margin-top: 5px;
vertical-align: middle;
margin: 0 0 9px;
margin-block-start: 1em;
margin-block-end: 1em;
text-align: left;
}
.productCard__likeWrap {
position: absolute;
top: -5px;
right: 0;
padding: 0;
height: 40px;
line-height: 37px;
white-space: normal;
display: inline-block;
margin-bottom: 0;
font-weight: normal;
text-align: center;
}
`;

codesandbox

https://codesandbox.io/s/likepractice-tpcv7l?file=/src/components/Clothes.jsx

可能有许多方法,但假设目标是使like按钮对单个项目起作用并将喜欢的项目保存在商店中,我认为在用例中使用数组作为状态的解决方案是合适的。

修改后的分叉演示:codesandbox

将状态配置为数组并创建匹配的reducer,此处产品id在喜欢时保存到状态数组中,但这是可选的方法。

const initailState = {
isClick: [],
};
const CheckLike = (state = initailState, action) => {
switch (action.type) {
case "True":
return {
...state,
isClick: [...state.isClick, action.id],
};
case "False":
return {
...state,
isClick: state.isClick.filter((id) => id !== action.id),
};
default:
return {
...state,
};
}
};

编辑事件处理程序以分派要从状态数组中添加或删除的项目id:

const setHide = (id) => {
dispatch({ type: "False", id });
};
const setShow = (id) => {
dispatch({ type: "True", id });
};

检查产品idcontent.id是否作为呈现图标的条件包含在状态数组中,并连接图标以将content.id发送到事件:

<div className="productCard__likeWrap">
{isClick.includes(content.id) ? (
<div
onClick={() => {
setHide(content.id);
}}
>
<FontAwesomeIcon icon={faHeart} />
</div>
) : (
<div
onClick={() => {
setShow(content.id);
}}
>
<FontAwesomeIcon icon={faHome} />
</div>
)}
</div>

如果我猜对了,你的问题是按钮点击改变了所有的按钮。

对于这个问题,您不需要redux。当你想管理在多个组件(如会话)中使用的全局状态时,可以使用redux。

解决这个问题的方法是,为每个产品卡创建一个新组件,并在那里管理按钮的状态。

和存储愿望清单上的产品,您可以将其存储在redux中。

最新更新