animation - component - Redux/Flux(con ReactJS) y animación
react show hide animation (2)
Estoy aprendiendo React + Redux y no entiendo la forma correcta de hacer las animaciones. Vamos a hablar con el ejemplo:
Por ejemplo, tengo una lista y me gustaría eliminar elementos al hacer clic. Eso es muy fácil si no tengo efectos de animación allí: REMOVE_ITEM
acción REMOVE_ITEM
al hacer clic, el reductor elimina el elemento de la tienda y reacciona re-render html.
Agreguemos una animación de eliminar la línea de pedido al hacer clic. Entonces, cuando el usuario hace clic en un elemento, quiero ejecutar un efecto sofisticado de la eliminación de líneas de pedido y ... ¿cómo? Puedo pensar en varias formas de hacerlo:
1) Al hacer clic despacho la acción REMOVE_ITEM
, luego reducer marcar un elemento como goingToBeDeleted
en Store, luego reaccionar representa ese elemento con una clase de .fancy-dissolve-animation
y ejecuto un temporizador para despachar la segunda acción REMOVE_ITEM_COMPLETED
. No me gusta esta idea, porque todavía no está claro cómo agregar animaciones JS aquí (por ejemplo, con TweenMax
) y ejecuto un temporizador JS para volver a procesar cuando termina la animación CSS. No suena bien
2) ITEM_REMOVE_PROGRESS
acciones de ITEM_REMOVE_PROGRESS
con un intervalo de ~ 30ms, y store tiene algún "valor" que representa el estado actual de la animación. No me gusta también, ya que me obligaría a copiar la tienda ~ 120 veces durante ~ 2 segundos de animación (digamos, quiero una animación suave de 60 fps) y eso es simplemente una pérdida de memoria.
3) Haz una animación y envía REMOVE_ITEM
solo después de que termine la animación. Esa es la forma más adecuada en que puedo pensar, pero aún así me gustaría que las cosas cambien en la tienda justo después de que el usuario realice la acción. Por ejemplo, la animación puede demorar más de unos pocos segundos y REMOVE_ITEM
podría sincronizarse con un servidor: no hay ninguna razón para esperar a que la animación termine para realizar una llamada a la API de back-end.
Gracias por leer, ¿alguna sugerencia?
Las acciones instantáneas son problemáticas en redux, lo que ahorra estado, por lo que si enviamos acción y cambiará de tienda, este cambio en la tienda estará disponible en los siguientes estados, por lo que podemos tener una situación en la que la animación se muestre una y otra vez. .
Mi solución para las acciones instantáneas de reducción es agregar alguna identificación como (Código de ejemplo de acción):
{
type:"SOME_ANIMATION",
id: new Date().getTime() //we get timestamp of animation init
}
A continuación, en el componente que ejecuta animaciones, guarde la última identificación de la animación y, si coincide, no haga la animación. Utilizo el estado del componente, por ejemplo, (código de componente):
componentDidUpdate (){
if (this.lastAnimationId===this.props.animation.id)
return; //the same animation id so do not do anything
//here setState or do animation because it is new one
this.lastAnimationId=this.props.animation.id; //here set new id of last abnimation
}
Gracias ID , podemos tener solo una acción sin acciones que están invirtiendo el estado. Invertir acciones después del tiempo de espera puede causar problemas porque si otra acción (que está conectada con el componente) se enviará antes de la acción inversa, entonces la animación puede comenzar de nuevo.
Los inconvenientes de mi enfoque propuesto son que los datos de animación existen en estado, pero también existe una identificación de animación que nos da información al respecto. Entonces podemos decir que la tienda guarda la última animación enviada.
React tiene una gran solución a este problema en la clase de ayuda ReactCSSTransitionGroup (ver https://facebook.github.io/react/docs/animation.html ). Con esta opción, React lo cuida, manteniendo el estado DOM para el niño tal como estaba en el último procesamiento. Simplemente envuelve tus artículos en un objeto ReactCSSTransitionGroup. Esto hace un seguimiento de sus hijos, y cuando se procesa con un elemento secundario eliminado, en lugar de representar sin el elemento secundario, se representa con el elemento secundario, pero agrega una clase CSS al elemento secundario (que puede usar para activar una animación CSS o puedes usar transiciones CSS para simplificar). Luego, después de un tiempo de espera (configurado como un apoyo pasado a ReactCSSTransitionGroup), se volverá a presentar de nuevo, con el niño eliminado del DOM.
Para usar ReactCSSTransitionGroup, necesitará npm instalar react-addons-css-transition-group, y luego requerir / importar ''react-addons-css-transition-group''. Los documentos de animación brindan información más detallada.
Una cosa para recordar: asegúrese de que los niños tengan llaves únicas e inmutables. Solo usar el índice como la clave hará que se comporte incorrectamente.