Algo así de simple debería lograrse fácilmente, sin embargo, me estoy tirando de los pelos por lo complicado que es.
Todo lo que quiero hacer es animar el montaje y desmontaje de un componente React, eso es todo. Esto es lo que he probado hasta ahora y por qué cada solución no funciona:
ReactCSSTransitionGroup
- No estoy usando clases CSS en absoluto, son todos estilos JS, por lo que esto no funcionará.ReactTransitionGroup
- Esta API de nivel inferior es excelente, pero requiere que uses una devolución de llamada cuando la animación esté completa, por lo que solo usar transiciones CSS no funcionará aquí. Siempre hay bibliotecas de animación, lo que lleva al siguiente punto:- GreenSock: la licencia es demasiado restrictiva para el uso comercial, en mi opinión.
- React Motion: esto parece genial, pero
TransitionMotion
es extremadamente confuso y demasiado complicado para lo que necesito. - Por supuesto, puedo hacer trucos como lo hace Material UI, donde los elementos se representan pero permanecen ocultos (
left: -10000px
) pero prefiero no seguir ese camino. Lo considero hacky y quiero que mis componentes se desmonten para que se limpien y no abarroten el DOM.
Quiero algo que sea fácil de implementar. En el monte, anime un conjunto de estilos; al desmontar, anime el mismo (u otro) conjunto de estilos. Hecho. También tiene que ser de alto rendimiento en múltiples plataformas.
He chocado contra una pared de ladrillos aquí. Si me falta algo y hay una manera fácil de hacerlo, avíseme.
transform: scale
.thing { color: #fff; }
) con estilos JS (const styles = { thing: { color: '#fff' } }
))Respuestas:
Esto es un poco largo, pero he usado todos los eventos y métodos nativos para lograr esta animación. No
ReactCSSTransitionGroup
,ReactTransitionGroup
etc.Cosas que he usado
onTransitionEnd
eventoComo funciona esto
mounted
) y con el estilo predeterminado (opacity: 0
)componentDidMount
(componentWillReceiveProps
para más actualizaciones) para cambiar el estilo (opacity: 1
) con un tiempo de espera (para que sea asíncrono).opacity: 0
)onTransitionEnd
, elimine desmontar el elemento del DOM.Continúe el ciclo.
Repase el código, lo entenderá. Si necesita alguna aclaración, deje un comentario.
Espero que esto ayude.
fuente
onTransitionEnd
? No lo veo en los documentos de React.componentWillReceiveProps
puedes devolver algo? ¿Dónde puedo leer más sobre eso?Parent
componente, se hace referencia athis.transitionEnd
Usando el conocimiento obtenido de la respuesta de Pranesh, se me ocurrió una solución alternativa que es configurable y reutilizable:
Uso:
Y finalmente, en el
render
método de otro componente :fuente
componentWillLeave()
ycomponentWillEnter()
cómo te llamanAnimatedMount
?Aquí está mi solución usando la nueva API de hooks (con TypeScript), basada en esta publicación , para retrasar la fase de desmontaje del componente:
Uso:
Enlace CodeSandbox .
fuente
Contrarresté este problema durante mi trabajo y, por simple que parezca, realmente no está en React. En un escenario normal en el que renderiza algo como:
a medida que
this.state.show
cambia, los niños se montan / desmontan de inmediato.Un enfoque que tomé fue crear un componente contenedor
Animate
y usarlo comoahora como
this.state.show
cambios, podemos percibir cambios de propgetDerivedStateFromProps(componentWillReceiveProps)
y crear etapas de render intermedias para realizar animaciones.Empezamos con Static Stage cuando los niños están montados o desmontados.
Una vez que detectamos los
show
cambios de bandera, ingresamos a Prep Stage donde calculamos las propiedades necesarias comoheight
ywidth
desdeReactDOM.findDOMNode.getBoundingClientRect()
.Luego, ingresando al estado animado, podemos usar la transición css para cambiar la altura, el ancho y la opacidad de 0 a los valores calculados (o a 0 si se desmonta).
Al final de la transición, usamos
onTransitionEnd
api para volver alStatic
escenario.Hay muchos más detalles sobre cómo las etapas se transfieren sin problemas, pero esta podría ser una idea general :)
Si alguien está interesado, creé una biblioteca React https://github.com/MingruiZhang/react-animate-mount para compartir mi solución. Cualquier comentario bienvenido :)
fuente
Creo que usar
Transition
fromreact-transition-group
es probablemente la forma más fácil de realizar un seguimiento del montaje / desmontaje. Es increíblemente flexible. Estoy usando algunas clases para mostrar lo fácil que es de usar, pero definitivamente puedes conectar tus propias animaciones JS utilizandoaddEndListener
prop, con lo que también he tenido mucha suerte usando GSAP.Sandbox: https://codesandbox.io/s/k9xl9mkx2o
Y aquí está mi código.
fuente
show
prop ayH1
hacer toda la lógica dentro del componente con estilo. Como ...animation: ${({ show }) => show ? entranceKeyframes : exitKeyframes} 300ms ease-out forwards;
Movimiento del encuadre
Instale framer-motion de npm.
fuente
Para aquellos que están considerando reaccionar-movimiento, animar un solo componente cuando se monta y desmonta puede ser abrumador de configurar.
Hay una biblioteca llamada react-motion-ui-pack que hace que este proceso sea mucho más fácil de comenzar. Es un envoltorio alrededor de react-motion, lo que significa que obtienes todos los beneficios de la biblioteca (es decir, puedes interrumpir la animación, hacer que ocurran varios desmontajes al mismo tiempo).
Uso:
Enter define cuál debería ser el estado final del componente; dejar es el estilo que se aplica cuando se desmonta el componente.
Es posible que descubra que una vez que haya usado el paquete de interfaz de usuario un par de veces, la biblioteca de reacción-movimiento podría dejar de ser tan abrumadora.
fuente
Animar las transiciones de entrada y salida es mucho más fácil con react-move .
ejemplo en codesandbox
fuente
Esto se puede hacer fácilmente usando el
CSSTransition
componente dereact-transition-group
, que es como las bibliotecas que mencionaste. El truco es que necesitas envolver el componente CSSTransition sin un mecanismo de mostrar / ocultar como haría normalmente .IE{show && <Child>}...
De lo contrario usted está ocultando la animación y que no funcionará. Ejemplo:fuente
Aquí mis 2 centavos: gracias a @deckele por su solución. Mi solución se basa en la suya, es la versión del componente con estado, completamente reutilizable.
aquí mi caja de arena: https://codesandbox.io/s/302mkm1m .
aquí mi snippet.js:
fuente
Así es como resolví esto en 2019, mientras hacía una ruleta de carga. Estoy usando componentes funcionales de React.
Tengo un componente de la aplicación principal que tiene un componente Spinner secundario .
La aplicación tiene un estado para indicar si la aplicación se está cargando o no. Cuando se carga la aplicación, Spinner se procesa normalmente. Cuando la aplicación no se está cargando (
isLoading
es falso) Spinner se renderiza con el propshouldUnmount
.App.js :
Spinner tiene un estado para si está oculto o no. Al principio, con los accesorios y el estado predeterminados, Spinner se representa normalmente. La
Spinner-fadeIn
clase lo anima desvaneciéndose. Cuando Spinner recibe el accesorio,shouldUnmount
lo renderiza con elSpinner-fadeOut
clase en su lugar, animándolo desvaneciéndose.Sin embargo, también quería que el componente se desmontara después de desvanecerse.
En este punto, intenté usar el
onAnimationEnd
evento sintético React, similar a la solución de @ pranesh-ravi anterior, pero no funcionó. En su lugar, solíasetTimeout
configurar el estado como oculto con un retraso de la misma duración que la animación. Spinner se actualizará después del retraso conisHidden === true
y no se procesará nada.La clave aquí es que el padre no desmonta al niño, le dice al niño cuándo debe desmontar y el niño se desmonta solo después de que se encarga de su tarea de desmontaje.
Spinner.js :
Spinner.css:
fuente
También necesitaba urgentemente la animación de un solo componente. Me cansé de usar React Motion pero me estaba tirando de los pelos por un problema tan trivial ... (cosa). Después de buscar en Google, encontré esta publicación en su repositorio de git. Espero que ayude a alguien ...
Referenciado desde y también el crédito . Esto funciona para mí a partir de ahora. Mi caso de uso fue un modal para animar y desmontar en caso de carga y descarga.
fuente
Sé que hay muchas respuestas aquí, pero todavía no encontré una que se adapte a mis necesidades. Quiero:
Después de muchas horas de tocar el violín, tengo una solución que funciona, diría que al 90%. Escribí la limitación en un bloque de comentarios en el siguiente código. Todavía me encantaría una solución mejor, pero esta es la mejor que he encontrado, incluidas las otras soluciones aquí.
Si tiene un componente que desea fundir de entrada / salida, envuélvalo en
<Fade>
Ej.<Fade><MyComponent/><Fade>
.Tenga en cuenta que esto se usa
react-bootstrap
para los nombres de clase y para<Container/>
, pero ambos podrían reemplazarse fácilmente con CSS personalizado y un archivo antiguo normal<div>
.fuente
Si uso
Velocity
oAnimeJS
biblioteca al nodo animado directamente (en lugar decss
osetTimeout
), a continuación, descubrí que puede diseñar unahook
para proporcionar el estado de la animaciónon
y la funciónonToggle
de la animación para iniciar la animación (por ejemplo, deslizamiento, atenuación).Básicamente, lo que hace el gancho es activar y desactivar la animación, y luego actualizar en
on
consecuencia. Por lo tanto, podemos obtener el estado de la animación con precisión. Sin hacerlo respondería ad-hocduration
.El uso es el siguiente,
y la implementación animada podría ser,
fuente
Puede usar React SyntheticEvent para eso.
Con eventos como onAnimationEnd o onTransitionEnd puedes lograrlo.
React Docs: https://reactjs.org/docs/events.html#animation-events
Ejemplo de código: https://dev.to/michalczaplinski/super-easy-react-mount-unmount-animations-with-hooks-4foj
fuente