Reputation: 367
I have a problem with css transition, i use styled component and the element add its className based on the changing of react useState which is triggered by onClick back and forth,
here is the part of the code that dont work as expected:
export const SearchProduct = ({ product }) => {
const [descStatus, setdescStatus] = useState(false);
const handleDesc = () => {
setdescStatus(!descStatus);
};
return (
<li>
<Item>
<Photo>
<img src={`${product.productImg}`} alt={product.productTitle}></img>
</Photo>
<Information>
<h3> {product.productTitle} </h3>
<Desclook>
<div className={descStatus ? 'active' : null} onClick={handleDesc}>
{descStatus ? 'Close' : 'See Desc ...'}
</div>
</Desclook>
{descStatus && (
<Description --> this is part that dont work
className={descStatus ? 'showContent content' : 'content'}
>
{product.productDesc}
</Description>
)}
Here is the styled components part :
const Description = styled.p`
margin: 10px;
padding: 0;
transition: all 0.3s ease-in-out;
&.content {
height: 0;
overflow: hidden;
}
&.showContent {
height: 70px;
overflow-y: scroll;
}
`;
Does anybody have any idea what happened with my code here cause i'm kinda new to react and styled component
Upvotes: 1
Views: 5711
Reputation: 56
Remove the check for descStatus
and always render <Description>
instead.
So instead of this:
{descStatus && (
<Description
className={descStatus ? 'showContent content' : 'content'}
>
{product.productDesc}
</Description>
)}
Do this:
<Description
className={descStatus ? 'showContent content' : 'content'}
>
{product.productDesc}
</Description>
The reason behind this is a CSS transition needs to transition from a different value than the current value. In your code when you check if descStatus
is true
before rendering, your Description
component will never have the className="content"
and will always be rendered initially with a height of 70px, so no transition will occur.
Upvotes: 3
Reputation: 41
Hey you can solve it easily if you send the state as a prop instead of setting className And you should update the state based on previous state and as useState setter sets the state asynchronously you might need asynchronous version of setState this is irrelevant for this problem but can cause problems in some cases
const handleDesc = () => {
setdescStatus(p => !p);
};
For the styled component part
<Description --> this is part that dont work
show={descStatus}
>
{product.productDesc}
</Description>
and inside the styled component you can handle it like
import styled,{css} from 'styled-components';
const Description = styled.p`
margin: 10px;
padding: 0;
transition: all 0.3s ease-in-out;
//content class styles applied by default
height: 0;
overflow: hidden;
//these styles will be applied only if show is true (css you can import from
//styled component as a named import)
${({show}) => show && css`
height: 70px;
overflow-y: scroll;
`}
`;
Upvotes: 1