React CSS Keyframes - animate when state removes component from DOM - javascript

I'm struggling to use CSS Keyframes with React.
I can get them to work when the component is mounted but when the component is unmounted the CSS transitions don't get a chance to animate before the state removes it from the DOM.
I'm not keen on doing this with a JS library when it feels like there should be a way to do this with good old CSS.
I've got a codepen that I put together to show what I've got so far.
https://codesandbox.io/s/react-hooks-usestate-forked-dhvu7?file=/src/styles.css
At the end of the animation I'd like the component to be unmounted I don't want it to stay in the dom.
Thanks in advance.

You can use css keyframe and use onAnimationEnd event handler to trigger state change after the animation is finished. Also you can add style={{ animationFillMode: "forwards" }} to the node to preserve the CSS properties of the last keyframe before removing it from the DOM.
Example:
{removeDom && (<button
style={{ animationFillMode: "forwards" }}
className="some animation class"
onAnimationEnd={()=>setRemoveDom(true)}
/>)}

For anyone else wanting a solution this article got me to where I wanted to be
https://czaplinski.io/blog/super-easy-animation-with-react-hooks/

Related

re-render vs visibility hidden

I have a simple component of conditional rendering.
And I can make 2 ways for this.
function SimpleComponent({ visible }){
return (
<button style={{position: 'absolute'}}>
{visible && <p>Visible!</p>}
<p style={{ visibility: `${visible ? 'visible' : 'hidden' }}>Visible!</p>
</button>
);
}
But I am not sure which is a better way for efficiency.
Please give me an idea or opinion about it.
It really depends on your needs. If you want to hide the element, but do not remove it from the DOM tree (so you can have access to it - apply some animations, pop it out smoothly, measure element height/width etc), use css visibility property.
If you just want to hide it and you don't want to access it while it's hidden, use condition visible && .... That element won't be rendered in the DOM tree at all.
Note: In matter of efficiency - the second approach is better since the less elements in the DOM tree, the better.
Note also that even if element has applied visibility: hidden property, it still takes space in your app (in the viewport) and can affect other elements position.

How can I get what element is being hovered using react?

I have an unordered list with anchor (<a>) tags and I need to apply some style based on what link the mouse is hovering.
Is there a way for me to access the classes of the element that is being hovered?
You can create an Item component that insides manages state to see if the rendered item is being hovered or not with the onMouseEnter and onMouseLeave functions. But since you are trying to modify the styling of the elements for such basic action as being hovered, you should keep with just CSS, targeting the HTML element with :hover selector.
In the first approach every Item component will have that state so then in the style={} you can do style={isHovered ? {background: "red"} : null} supposing you have an isHovered state.
I would recommend you styled-components, they are great.
In ReactJS the events have name like onMouseOver, you can see other events here.
For your case you can write like below:
<a onMouseOver={() => { console.log('hovered') }}> ~~~
If you want to apply a style to an element on hover, use the :hover CSS selector...
#mydiv:hover {
background-color:red;
}
<div id="mydiv">Text to hover on!</div>
If you can change the CSS only to get the style changes you want, that's ideal compared to using code to change the styles. With a 100% CSS solution, there's other advantages....
You can have people who only know CSS maintain and update the code.
You can disable styles without disabling code.
You can update styles without breaking code.
A CSS checker will catch issues in a .css file that would be missed if they were encoded in raw JS.
Source: MDN Documentation - :hover

Change CSS during an animation

I have some buttons with their CSS style.
When an animation starts I would like to change their style for the duration of the animation.
Stuff like changing the color, changing the pointer, changing the hover; to make them look "disabled" basically.
I have a global var which is "true" while the animations runs, and turns "false" when the animation is not running.
In order to achieve this goal, I have tried many things, but none of them worked, I tried:
changing the name of the class based on the var value, and create two different CSS styles -> didn't work because it didn't get updated with the change of the var
changing the style within REACT inside the function when the animation is called and changing it back when it's over. Using: document.getElementById("firstOne").style =
The second option it's the only one that actually worked well. The problem I can't edit back the hover to where it was before.
The question:
Is there a way to change the hover from React? Something like:
document.getElementById("firstOne").style = ;
If not, is there a way to just tell it "from now just follow the style written on the CSS file"?. To kind of setting the style back to before.
If not, any other ideas on how to achieve my goal?
Thank you

How can I best implement this React Transition?

I am attempting to create an easy-to-use UI/UX selection system.
Essentially, on the viewport, I first have 3 "difficulty" components that choose what "difficulty level" you want.
Once clicked, they should then transition to the next selection phase, which would be "male" or "female".
Clicking this button should move/remove the difficulty level component to the left (out of the viewport), and move the sex selection into the viewport.
How would I implement this?
I also plan on implementing a "Go back" feature as well in the future, so that users can go back and forth from Difficulty and Sex components.
My ideas
Once the button is clicked, I just use CSS to transition the difficulty component out of the viewport, and the "sex" component into the viewport. After the transition, I give that component a display: none to remove it completely from the user.
Concerns: This doesn't seem efficient. Should I be removing the component entirely? If so, where does one begin to do that?
Another method would be to remove/add the components as needed...which I believe would require using the ComponentDidMount() and ComponentDidUnmount() functions, and then using the React Transition Group library to somehow transition them out?
Here is an excellent, Picasso-like, hand-drawn example from myself:
There is how to do the transition.
Typically, setting display: none stops any sort of animation, which you don't want to do.
export default class Modal extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return (
nextProps.show !== this.props.show ||
nextProps.children !== this.props.children
);
}
render() {
const { show, children } = this.props;
return (
<div
style={{
transform: show ? 'translateY(0)' : 'translateY(-100vh)',
opacity: show ? 1 : 0,
}}
>
{children}
</div>
);
}
}
Note that returning false from shouldComponentUpdate will stop re-rendering the modal and its children.
The children could be anything or nothing. So when you don't want to show it, render an empty div outside view window is very efficient.
Key takeaway
display: none shouldn't need most of the time. It doesn't support animation, and render function can return <div /> or null.
React components will re-render when received new props or updated state, regardless display type and window position.
Mare sure have a clear understanding on rendering lifecycle, not all mounting/updating functions can setState, and you can stop re-rendering manually.

How to stop CSS3 transition

I want to stop a transition that is in progress.
I have found a few references[1][2] scattered around the internet but I can't seem to piece it together.
Here's a fiddle of the first suggestion (With jQuery and CSS Transit for context): http://jsfiddle.net/thomseddon/gLjuH/
Thanks
[1] https://twitter.com/evilhackerdude/status/20466821462
[2] github.com/madrobby/zepto/issues/508
So I figured it out: http://jsfiddle.net/thomseddon/gLjuH/3/
The trick is to set each css property you are animating to its current value (possibly mid transition) like: $(this).css('prop', $(this).css('prop')); (Probably would want to store all properties in an object in the element with $(this).data(props); and loop through them).
Once you have explicitly set the properties you can run a 0s animation to override the previous animation and effectively halt the element.
There's a much simpler solution. If you want to just stop the transition (and not pause it). Just set the css to current computed style. For example in a custom scrolling solution, where top is transitioned property.
element.style.top=getComputedStyle(element).top;
and that's it.

Categories

Resources