如何动态呈现图标?
How can I render an icon dynamically?
如何只动态渲染图标 cartIcon?因为现在,就像下面的代码,当我用鼠标进入组件时,所有出现的图标不仅是单个产品的图标。
我认为是因为地图,但我如何才能只渲染它?
interface IItemsProps {
products: ProductsType;
}
const Items: React.FunctionComponent<IItemsProps> = ({ products }) => {
const [state, setState] = React.useState<boolean>(false);
const handleMouseEnter = () => {
setState(true);
};
const handleMouseLeave = () => {
setState(false);
};
const itemUI = products.map((item: SingleProductsType) => {
const { name, price, _id } = item;
return (
<WrapperSingleItem key={uuidv4()} id={_id}>
{state && <IconsCarts />} ** //HERE I NEED TO SHOW THIS COMPONENT ONLY WHEN I
// ENTER WITH THE MOUSE BUT ONLY FOR THE SELECTED
//PRODUCT NOT ALL OF THEM **
<ImgProduct
src={mouse}
alt={name}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
/>
<WrapperTextProduct>
<TextName>{name}</TextName>
<div>
<TextActualPrice>$ {price}</TextActualPrice>
<TextPreviousPrice>
$ {Math.trunc((price * 20) / 100 + price)}.00
</TextPreviousPrice>
</div>
</WrapperTextProduct>
</WrapperSingleItem>
);
});
return <WrapperItems>{itemUI}</WrapperItems>;
};
export default Items;
在 state 中使用布尔值,您只知道是否显示图标,但是知道 哪个 列表项显示图标呢?与其将状态作为布尔值,不如我们使用产品的索引。
interface IItemsProps {
products: ProductsType;
}
const Items: React.FunctionComponent<IItemsProps> = ({ products }) => {
const [state, setState] = React.useState<number>(-1);
const handleMouseEnter = (index) => {
setState(index);
};
const handleMouseLeave = () => {
setState(-1);
};
const itemUI = products.map((item: SingleProductsType, index: number) => {
const { name, price, _id } = item;
return (
<WrapperSingleItem key={uuidv4()} id={_id}>
{state === index && <IconsCarts />} ** //Check if index matches state before showing icon **
<ImgProduct
src={mouse}
alt={name}
onMouseEnter={() => handleMouseEnter(index)}
onMouseLeave={handleMouseLeave}
/>
<WrapperTextProduct>
<TextName>{name}</TextName>
<div>
<TextActualPrice>$ {price}</TextActualPrice>
<TextPreviousPrice>
$ {Math.trunc((price * 20) / 100 + price)}.00
</TextPreviousPrice>
</div>
</WrapperTextProduct>
</WrapperSingleItem>
);
});
return <WrapperItems>{itemUI}</WrapperItems>;
};
export default Items;
现在显示图标的条件是列表项的索引是否与状态中的索引匹配。然后我们将索引传递给 handleMouseEnter 以将状态设置为该索引,handleMouseLeave 会将其重置为 -1。
您可以将悬停的 _id
存储在状态中,这样您就知道它是哪一个了。
const [state, setState] = React.useState<string | null>(null); // or `number` ?
然后
{state === _id && <IconsCarts />}
<ImgProduct
src={mouse}
alt={name}
onMouseEnter={() => setState(_id)}
onMouseLeave={() => setState(null)}
/>
或者您可以将 useState
移动到一个称为地图的每个循环的组件中,以便每个项目都有自己的私有状态。
function MyItem({item}: { item: SingleProductsType }) {
const [state, setState] = React.useState<boolean>(false);
const { name, price, _id } = item;
return (
<WrapperSingleItem key={uuidv4()} id={_id}>
{state && <IconsCarts />}
<ImgProduct
src={mouse}
alt={name}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
/>
<WrapperTextProduct>
<TextName>{name}</TextName>
<div>
<TextActualPrice>$ {price}</TextActualPrice>
<TextPreviousPrice>
$ {Math.trunc((price * 20) / 100 + price)}.00
</TextPreviousPrice>
</div>
</WrapperTextProduct>
</WrapperSingleItem>
);
}
现在您可以:
{products.map((item: SingleProductsType) => <MyItem item={item} />}
最后,如果您只想 show/hide 使用鼠标输入某个元素时的购物车图标,则此解决方案可能有点矫枉过正。您可以单独使用 CSS 来完成此操作,这将是一个更简洁的解决方案,因为它不需要任何 javascript 代码,而且您根本不必跟踪状态。
.item {
width: 100px;
height: 100px;
background: #aaa;
margin: 10px;
}
.item button {
display: none;
}
.item:hover button {
display: block;
}
<div class="item">
Foo
<button>Add to cart</button>
</div>
<div class="item">
Bar
<button>Add to cart</button>
</div>
<div class="item">
Baz
<button>Add to cart</button>
</div>
如何只动态渲染图标 cartIcon?因为现在,就像下面的代码,当我用鼠标进入组件时,所有出现的图标不仅是单个产品的图标。
我认为是因为地图,但我如何才能只渲染它?
interface IItemsProps {
products: ProductsType;
}
const Items: React.FunctionComponent<IItemsProps> = ({ products }) => {
const [state, setState] = React.useState<boolean>(false);
const handleMouseEnter = () => {
setState(true);
};
const handleMouseLeave = () => {
setState(false);
};
const itemUI = products.map((item: SingleProductsType) => {
const { name, price, _id } = item;
return (
<WrapperSingleItem key={uuidv4()} id={_id}>
{state && <IconsCarts />} ** //HERE I NEED TO SHOW THIS COMPONENT ONLY WHEN I
// ENTER WITH THE MOUSE BUT ONLY FOR THE SELECTED
//PRODUCT NOT ALL OF THEM **
<ImgProduct
src={mouse}
alt={name}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
/>
<WrapperTextProduct>
<TextName>{name}</TextName>
<div>
<TextActualPrice>$ {price}</TextActualPrice>
<TextPreviousPrice>
$ {Math.trunc((price * 20) / 100 + price)}.00
</TextPreviousPrice>
</div>
</WrapperTextProduct>
</WrapperSingleItem>
);
});
return <WrapperItems>{itemUI}</WrapperItems>;
};
export default Items;
在 state 中使用布尔值,您只知道是否显示图标,但是知道 哪个 列表项显示图标呢?与其将状态作为布尔值,不如我们使用产品的索引。
interface IItemsProps {
products: ProductsType;
}
const Items: React.FunctionComponent<IItemsProps> = ({ products }) => {
const [state, setState] = React.useState<number>(-1);
const handleMouseEnter = (index) => {
setState(index);
};
const handleMouseLeave = () => {
setState(-1);
};
const itemUI = products.map((item: SingleProductsType, index: number) => {
const { name, price, _id } = item;
return (
<WrapperSingleItem key={uuidv4()} id={_id}>
{state === index && <IconsCarts />} ** //Check if index matches state before showing icon **
<ImgProduct
src={mouse}
alt={name}
onMouseEnter={() => handleMouseEnter(index)}
onMouseLeave={handleMouseLeave}
/>
<WrapperTextProduct>
<TextName>{name}</TextName>
<div>
<TextActualPrice>$ {price}</TextActualPrice>
<TextPreviousPrice>
$ {Math.trunc((price * 20) / 100 + price)}.00
</TextPreviousPrice>
</div>
</WrapperTextProduct>
</WrapperSingleItem>
);
});
return <WrapperItems>{itemUI}</WrapperItems>;
};
export default Items;
现在显示图标的条件是列表项的索引是否与状态中的索引匹配。然后我们将索引传递给 handleMouseEnter 以将状态设置为该索引,handleMouseLeave 会将其重置为 -1。
您可以将悬停的 _id
存储在状态中,这样您就知道它是哪一个了。
const [state, setState] = React.useState<string | null>(null); // or `number` ?
然后
{state === _id && <IconsCarts />}
<ImgProduct
src={mouse}
alt={name}
onMouseEnter={() => setState(_id)}
onMouseLeave={() => setState(null)}
/>
或者您可以将 useState
移动到一个称为地图的每个循环的组件中,以便每个项目都有自己的私有状态。
function MyItem({item}: { item: SingleProductsType }) {
const [state, setState] = React.useState<boolean>(false);
const { name, price, _id } = item;
return (
<WrapperSingleItem key={uuidv4()} id={_id}>
{state && <IconsCarts />}
<ImgProduct
src={mouse}
alt={name}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
/>
<WrapperTextProduct>
<TextName>{name}</TextName>
<div>
<TextActualPrice>$ {price}</TextActualPrice>
<TextPreviousPrice>
$ {Math.trunc((price * 20) / 100 + price)}.00
</TextPreviousPrice>
</div>
</WrapperTextProduct>
</WrapperSingleItem>
);
}
现在您可以:
{products.map((item: SingleProductsType) => <MyItem item={item} />}
最后,如果您只想 show/hide 使用鼠标输入某个元素时的购物车图标,则此解决方案可能有点矫枉过正。您可以单独使用 CSS 来完成此操作,这将是一个更简洁的解决方案,因为它不需要任何 javascript 代码,而且您根本不必跟踪状态。
.item {
width: 100px;
height: 100px;
background: #aaa;
margin: 10px;
}
.item button {
display: none;
}
.item:hover button {
display: block;
}
<div class="item">
Foo
<button>Add to cart</button>
</div>
<div class="item">
Bar
<button>Add to cart</button>
</div>
<div class="item">
Baz
<button>Add to cart</button>
</div>