es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

React Native Reanimated runOnJS: no actualiza el estado cada vez.

Tengo una lista de elementos que deberían cambiar de estado cuando se deslizan más allá de un umbral determinado. Estoy utilizando runOnJs para llamar a una función que cambie el estado. Ahora, cuando deslizo un elemento por primera vez, actualiza su estado, pero después de eso, cada deslizamiento no hace nada. ¿Alguien puede explicarme qué me falta aquí?

“`
let [cleaned, setCleaned] = useState(false);

let handleCleanPress = () => {
console.log(clean);
setCleaned(!cleaned);
translateX.value = withTiming(0);
};

let panGesture = useAnimatedGestureHandler<pangesturehandlergestureevent>({
onStart: (event, context) => {
context.startX = translateX.value;
},
onActive: (event, context) => {
let start = context.startX + event.translationX;
if (start < 0) {
translateX.value = start;
}
},
onEnd: () => {
let shouldTriggerClean = translateX.value < translateXThreshold;
translateX.value =
translateX.value >= snapThreshold && translateX.value < -BUTTON_WIDTH
? withTiming(snapPoint, { duration: 200 })
: withTiming(0, { duration: 200 });

<pre><code> if (shouldTriggerClean) {
runOnJS(handleCleanPress)();
}
},
</code></pre>

});
“`

Tags:  ,

Answer

  1. Avatar for davy.ai

    Parece que el problema está con la función runOnJS que se llama en cada deslizamiento, lo que puede generar conflictos con el estado actual del componente. Para solucionar esto, puedes intentar usar el gancho useCallback para memoizar la función handleCleanPress y evitar renderizados innecesarios.

    Aquí tienes una versión actualizada del código:

    import { useCallback, useState } from 'react';
    import { useAnimatedGestureHandler, withTiming } from 'react-native-reanimated';
    
    let [cleaned, setCleaned] = useState(false);
    
    const handleCleanPress = useCallback(() => {
      console.log(cleaned);
      setCleaned(!cleaned);
      translateX.value = withTiming(0);
    }, [cleaned]);
    
    let panGesture = useAnimatedGestureHandler({
      onStart: (_, context) => {
        context.startX = translateX.value;
      },
      onActive: (event, context) => {
        let start = context.startX + event.translationX;
        if (start < 0) {
          translateX.value = start;
        }
      },
      onEnd: () => {
        let shouldTriggerClean = translateX.value < translateXThreshold;
        translateX.value =
          translateX.value >= snapThreshold && translateX.value < -BUTTON_WIDTH
            ? withTiming(snapPoint, { duration: 200 })
            : withTiming(0, { duration: 200 });
    
        if (shouldTriggerClean) {
          handleCleanPress();
        }
      },
    });
    

    Al usar useCallback, la función handleCleanPress solo se recreará cuando sus dependencias (en este caso, cleaned) cambien. Esto asegura que la función pasada a runOnJS siempre refleje el estado actual del componente, permitiendo que el estado se actualice correctamente en cada deslizamiento.

Comments are closed.