我在更改电子商务元素中添加到购物车的商品的颜色时遇到一些问题。我可以做到这样,当单击该元素时,类会发生变化并且该元素会获得颜色。作为副作用,所有附带的元素也会变色。
“服务”组件
const Service = (props) => {
const context = useContext(ThemeContext)
return (
<>
<li className={context.cartItems.some(item => item.type === "service") ? "inCart" : ""}
onClick={() => { context.cartItems.some(item => item) ?
context.removeFromCart(props) : context.addToCart(props)}} >
{props.name}
</li>
</>
)
}
呈现上述组件的“Options”组件
const Options = () => {
const context = useContext(ThemeContext)
const serviceElements = servicesList.map(service =>
<Service key={service.id} id={service.id} name={service.name} type={service.type} /> )
return (
<div className={`Options-${context.theme}`}>
<ul>
{serviceElements}
</ul>
</div>
)
}
添加和从购物车中删除方法
function addToCart(newItem) {
cartItems.map(item => newItem.type === item.type && removeFromCart(item))
setCartItems(prevItems => [...prevItems, newItem])
}
function removeFromCart(itemToRemove) {
setCartItems(prevItems => prevItems.filter(item =>
`${item.id}-${item.type}` !== `${itemToRemove.id}-${itemToRemove.type}`))
}
SCSS
.Options-light {
.inCart {
background-color: blue;
}
最佳答案
看起来有些事情可以改变。首先,Service
中的 className
逻辑会将 inCart
添加到您的所有 li
中,因为它正在检查整个上下文数组,与当前的 props 无关。所以尝试一下:
context.cartItems.find(item => item.id === props.id) ? “inCart”:“”
还可以清理你的内容功能:
function addToCart(newItem) {
// Looks like you were trying to do a check to make sure that the item isn't
// already in the cart
const alreadyInCart = cartItems.some(item => item.id === newItem.id);
if (!alreadyInCart) {
setCartItems(prevItems => [...prevItems, newItem]);
}
}
function removeFromCart(itemToRemove) {
// I assume id is unique because you use it as a key for the Service component
setCartItems(prevItems => prevItems.filter(item => item.id !== itemToRemove.id));
}
我认为你可能最好使用 toggleCartItem
来让事情变得更干净,如果你以后的“购物车”服务只需要一个 id,那么你可以进一步清理。让我知道这是否更好一点:
const Options = () => {
const context = useContext(ThemeContext);
const serviceElements = servicesList.map(service =>
<Service
key={service.id}
id={service.id}
inCart={context.cartItems.some(id => service.id === id)}
/>
);
return (
<div className={`Options-${context.theme}`}>
<ul>
{serviceElements}
</ul>
</div>
)
}
const Service = (props) => {
const context = useContext(ThemeContext);
return (
<li
className={props.inCart ? "inCart" : ""}
onClick={() => toggleCartItem(props.id)}
>
{props.name}
</li>
)
}
function toggleCartItem(newItemId) {
const alreadyInCart = cartItems.some(id => id === newItemId);
if (alreadyInCart) {
setCartItems(prevIds => prevId.filter(id => id !== newItemId));
} else {
setCartItems(prevIds => [...prevIds, newItemId]);
}
}
关于javascript - 如何在 React 中设置单个 <li> 的样式而不是所有 <li> 的样式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59683030/