I have a storybook project and created a new custom component. I used a hover state and when I hover the component, it updates its className and it just works fine. Named: ProductSize
And then, I created a new component to group the ProductSize component and named it as ProductSizeGroup and grouped them by the Json inside the ProductSizeGroup stories.
And here is the final product screen:
Here, I want to see the sizes when I hover the boxes. But, it shows me all the sizes all alone like this. Apparently, I only want to see XSmall when I hover to XS, Small in S etc..:
Edit: Many people asked for the coding side and that is here - a live coding example:
https://codesandbox.io/s/usestateissue-10l4l
So, how to solve it?
Here is the ProductSizeGroup
component code displaying the ProductSize
items and hover-triggered sizes
const ProductSizeGroup: React.FC<IProductSizeGroupProps> = (props) => {
const { ProductSizes } = props;
const [inHover, setHover] = useState(false);
return (
<Box style={{ width: "100%" }}>
<Typography>
{" "}
Size:
{ProductSizes.map((products: any) =>
inHover ? products.name : undefined
)}
</Typography>
<Box display="flex" justifyContent="flex-start" p={1} m={1}>
{ProductSizes.map((products: any) => (
<Box
onMouseEnter={() => setHover(true)}
onMouseLeave={() => setHover(false)}
>
<ProductSize
inStock={products.inStock}
sizeText={products.sizeText}
name={products.name}
/>
</Box>
))}
</Box>
</Box>
);
};
The issue is that you're displaying the size via the following
Size:
{ProductSizes.map((products: any) =>
inHover ? products.name : undefined
)}
where inHover
is simply a Boolean value. So this will either show all name
values or nothing.
I think what would work better is something like the following where you set the hovered
state to the value you want and simply display it
const [hovered, setHovered] = useState<string | undefined>();
return (
<!-- snip -->
<Typography>Size: {hovered}</Typography>
<!-- snip -->
{ProductSizes.map(product => (
<Box
onMouseEnter={() => setHovered(product.name)}
onMouseLeave={() => setHovered(undefined)}
>
<!-- etc -->
</Box>
))}
)
Take note that I've also removed some of your any
typings in the sandbox.
In order to handle states, you can use the react context provider: https://reactjs.org/docs/context.html or react redux https://react-redux.js.org/ .
Depending on how many states you have and what you want to do with them you can choose one of the two. React-redux loads only the states you need, it is faster, but it has a specific structure that you need to follow. It is more complex at the beginning, but you can easier handle multiple states.
Context provider is already installed with react, it is easier to set up, but it is slower since it loads all states on each page load.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.