Cómo animar la reordenación del estado de matriz de reductores en React Native LayoutAnimation
¿Cómo puedo lograr una animación reordenante usando React Native LayoutAnimation cuando se actualiza una propiedad de Redux reducer?
Tengo un players
array en un reductor Redux, parece algo así:
jugadoresReducer.jugadores:
[{
"uuid": "681b04b5-5b39-4c6c-b21d-8a8a2240a0c7",
"name": "Tom",
"score": 190,
"online": false,
"isMe": null
}, {
"uuid": "02531db4-e61d-4754-bb4a-fef1a696bef4",
"name": "Dick",
"score": 10,
"online": false,
"isMe": null
}, {
"uuid": "51420a54-7563-4cd2-adf3-ccefc1b6ffca",
"name": "Harry",
"score": 170,
"online": false,
"isMe": null
}];
Cuando un reductor obtiene una actualización a través de una respuesta de websocket, la propiedad puntuación cambia en el objeto de array adecuado. Puedo confirmar con el plugin del navegador Chrome redux que cada estado objeto está siendo inmutable y el diff mostrado demuestra que;
Cuando el reductor actualiza el estado de mi componente funcional reordeno playersReducer.players
array con el sort
función para ordenar los jugadores por puntuación como así:
let players = [...props.playersReducer.players];
return (
{players
.sort((player1, player2) => (player1.score > player2.score) ? -1 : 1 )
.map((player, i) => {
return (
// player UI rendered here
)
He preparado LayoutAnimation.configureNext()
en el cuerpo del componente de función, que hace que un nuevo elemento sea añadido de otro reductor que demuestre que LayoutAnimation está funcionando;
const isFirstRender = React.useRef(true);
React.useEffect(() => {
if (isFirstRender.current) {
isFirstRender.current = false;
return;
}
/*business logic for component did update*/
LayoutAnimation.configureNext({
...LayoutAnimation.Presets.easeInEaseOut,
create: {property: "scaleXY"},
delete: {property: "scaleXY"},
update: {property: "scaleXY"}
})
});
¿Cómo puedo usar LayoutAnimation
para animar un efecto reordenante en mis componentes de jugador? Estoy tratando de lograr algo como esto:
Pregunta hecha hace 3 años, 5 meses, 0 días - Por csscraftsman
3 Respuestas:
-
Usted puede lograr este objetivo utilizando
Transitioning View
.import React, { useRef, useState } from 'react'; import { Button, SafeAreaView, FlatList, StyleSheet, Text, View } from 'react-native'; import { Transition, Transitioning } from 'react-native-reanimated'; const transition = (
item.toString()} renderItem={({ item }) => { return ( {item} Puedes revisar la demo Aquí..
Respondida el Dec 16, 2020 a las 11:03 - por codecanvas
Votos positivos: 0 | Votos negativos: 0 -
Para lograr una animación al reordenar los jugadores en tu componente al actualizarse el estado del array de jugadores en Redux, puedes seguir los siguientes pasos:
- Asegúrate de tener configurada la opción `useNativeDriver` en `true` en la configuración de `LayoutAnimation`. Esto es necesario para que las animaciones se ejecuten de manera suave y eficiente en React Native.
- Dentro de tu componente de función, puedes usar un efecto de `useEffect` que se active cada vez que el array de jugadores cambie. En este efecto, puedes configurar la animación de LayoutAnimation antes de que se realice la actualización del estado.
javascript const isFirstRender = React.useRef(true); React.useEffect(() => { if (!isFirstRender.current) { LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut, () => { // Lógica adicional después de la animación }); } else { isFirstRender.current = false; } }, [props.playersReducer.players]); // Escucha cambios en el array de jugadores
- Luego, dentro del `map` de los jugadores en tu JSX, puedes asignar una `key` única a cada jugador para que React pueda identificarlos correctamente durante las actualizaciones.
- Asegúrate de que en tu `sort` estás utilizando el operador correcto para ordenar de manera ascendente o descendente según tus necesidades.
Con estos pasos, deberías poder animar la reordenación de los jugadores en tu componente cuando se actualice el estado del array de jugadores en Redux. Recuerda también asegurarte de tener las librerías necesarias importadas para utilizar
LayoutAnimation
.Respondida el Dec 17, 2020 a las 10:58 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Paso 1: Crear una clave única para cada elemento de la lista
Para que React Native LayoutAnimation funcione correctamente con listas reordenadas, cada elemento de la lista debe tener una clave única. En tu caso, puedes usar la propiedad
uuid
como clave:Paso 2: Usar
LayoutAnimation.create()
yLayoutAnimation.update()
Cuando se actualiza la propiedad
score
de un jugador, desencadena una reordenación de la lista. Puedes usarLayoutAnimation.create()
cuando se agrega un nuevo elemento a la lista yLayoutAnimation.update()
cuando se actualiza un elemento existente:useEffect(() => { LayoutAnimation.configureNext({ ...LayoutAnimation.Presets.easeInEaseOut, create: { type: LayoutAnimation.Types.easeInEaseOut, property: LayoutAnimation.Properties.scaleXY, }, update: { type: LayoutAnimation.Types.easeInEaseOut, property: LayoutAnimation.Properties.scaleXY, }, }); }, [players]);
Paso 3: Usar
useAnimatedStyle()
Para animar la reordenación, puedes usar
useAnimatedStyle()
de React Native Animated para transformar el estilo de los elementos de la lista:const animatedStyle = useAnimatedStyle(() => { return { transform: [{ scale: animatedScale.value }], }; }); return
; En este ejemplo,
animatedScale
es una variable animada que controla la escala del elemento.Paso 4: Animar
animatedScale
Cuando se actualiza un elemento de la lista, puedes animar
animatedScale
usandoAnimated.timing()
:Animated.timing(animatedScale, { toValue: 1, duration: 200, useNativeDriver: true, }).start();
Esto animará la escala del elemento de 0 a 1 durante 200 milisegundos, creando un efecto de reordenación suave.
Ejemplo de código completo:
import { useAnimatedStyle } from 'react-native-reanimated'; import { Animated } from 'react-native'; const Player = ({ player }) => { const animatedScale = new Animated.Value(0); const animatedStyle = useAnimatedStyle(() => { return { transform: [{ scale: animatedScale.value }], }; }); useEffect(() => { Animated.timing(animatedScale, { toValue: 1, duration: 200, useNativeDriver: true, }).start(); }, []); return
; }; const PlayersList = ({ players }) => { LayoutAnimation.configureNext({ ...LayoutAnimation.Presets.easeInEaseOut, create: { type: LayoutAnimation.Types.easeInEaseOut, property: LayoutAnimation.Properties.scaleXY, }, update: { type: LayoutAnimation.Types.easeInEaseOut, property: LayoutAnimation.Properties.scaleXY, }, }); return players.map((player) => ); }; Respondida el Dec 17, 2020 a las 11:07 - por Gemini
Votos positivos: 0 | Votos negativos: 0