title: scrollHandler and scrollTo in animated scrollview
body: <p>Is there a way to use scrollHandler (for updating the shared value) and scrollTo together</p>
  <p><a href="https://snack.expo.dev/@haniq313/scrollview-with-handler-and-scrollto" rel="nofollow noreferrer">https://snack.expo.dev/@haniq313/scrollview-with-handler-and-scrollto</a></p>
  <p>Snack and code below.</p>
  <p>Problem is when i press the Next button the scrollTo works but also triggers the scrollHandler. If i disable the scrollHandler then it works fine. but then i cant manually swipe and change values. Need to make both work. Is there someway to call scrollTo and at the same time not have the scrollHandler triggered ?</p>
  <pre><code>import React, { useState } from 'react';
  import {
    Text,
    View,
    StyleSheet,
    ScrollView,
    Platform,
    SafeAreaView,
    TouchableOpacity,
  } from 'react-native';
  import Constants from 'expo-constants';
  import Animated, {
    Extrapolate,
    interpolate,
    runOnJS,
    useAnimatedRef,
    useAnimatedScrollHandler,
    useAnimatedStyle,
    useDerivedValue,
    useSharedValue,
    scrollTo,
  } from 'react-native-reanimated';
  import { Ionicons } from '@expo/vector-icons';
  
  const data = [
    'Jan',
    'Feb',
    'Mar',
    'Apr',
    'May',
    'Jun',
    'Jul',
    'Aug',
    'Sep',
    'Oct',
    'Nov',
    'Dec',
  ];
  
  // You can import from local files
  import AssetExample from './components/AssetExample';
  
  const ITEM_HEIGHT = 25;
  const ITEM_WIDTH = 200;
  const VISIBLE_ITEMS = 3;
  const FONT_SIZE = 16;
  
  const SpinnerItem = (props) =&gt; {
    const { idx, label, scrollY } = props;
  
    const focusedStyle = useAnimatedStyle(() =&gt; {
      const opacity = interpolate(
        scrollY.value,
        [(idx - 2) * ITEM_HEIGHT, (idx - 1) * ITEM_HEIGHT, idx * ITEM_HEIGHT],
        [0.3, 1, 0.3],
        Extrapolate.CLAMP
      );
  
      const rotate = interpolate(
        scrollY.value,
        [(idx - 2) * ITEM_HEIGHT, (idx - 1) * ITEM_HEIGHT, idx * ITEM_HEIGHT],
        [-60, 0, 60],
        Extrapolate.CLAMP
      );
  
      return {
        opacity,
        transform: [{ rotateX: rotate + 'deg' }],
      };
    }, [idx, scrollY]);
  
    const fontStyle = useAnimatedStyle(() =&gt; {
      const fontStyle = interpolate(
        scrollY.value,
        [(idx - 2) * ITEM_HEIGHT, (idx - 1) * ITEM_HEIGHT, idx * ITEM_HEIGHT],
        [FONT_SIZE, FONT_SIZE + 8, FONT_SIZE],
        Extrapolate.CLAMP
      );
  
      return {
        fontSize: fontStyle,
      };
    }, [idx, scrollY]);
  
    return (
      &lt;Animated.View
        style={[
          {
            alignItems: 'center',
            justifyContent: 'center',
            width: ITEM_WIDTH,
            height: ITEM_HEIGHT,
          },
          focusedStyle,
        ]}&gt;
        &lt;Animated.Text
          allowFontScaling={false}
          adjustsFontSizeToFit={false}
          style={[styles.label, fontStyle]}&gt;
          {label}
        &lt;/Animated.Text&gt;
      &lt;/Animated.View&gt;
    );
  };
  
  export default function App() {
    const [selectedIndex, setSelectedIndex] = useState(0);
    const scrollY = useSharedValue(0);
    const aref = useAnimatedRef();
    const scrollHandler = useAnimatedScrollHandler({
      onScroll: (event) =&gt; {
        scrollY.value = event.contentOffset.y;
        runOnJS(setSelectedIndex)(Math.round(scrollY.value / ITEM_HEIGHT));
      },
    });
  
    useDerivedValue(() =&gt; {
      scrollTo(aref, 0, scrollY.value, true);
    });
  
    const incrementScroll = () =&gt; {
      'worklet';
      scrollY.value = scrollY.value + ITEM_HEIGHT;
      if (scrollY.value &gt;= (data.length - 1) * ITEM_HEIGHT) scrollY.value = 0;
      runOnJS(setSelectedIndex)(Math.round(scrollY.value / ITEM_HEIGHT));
    };
  
    return (
      &lt;SafeAreaView
        style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}&gt;
        &lt;Text&gt;{'Selected Index: ' + selectedIndex}&lt;/Text&gt;
        &lt;View style={styles.container}&gt;
          &lt;TouchableOpacity
            onPress={() =&gt; {
              incrementScroll();
            }}&gt;
            &lt;Ionicons name=&quot;ios-arrow-down-sharp&quot; size={24} color=&quot;black&quot; /&gt;
          &lt;/TouchableOpacity&gt;
          &lt;Animated.ScrollView
            showsVerticalScrollIndicator={false}
            bounces={false}
            ref={aref}
            decelerationRate={Platform.OS === 'ios' ? 0 : 0.98}
            renderToHardwareTextureAndroid
            contentContainerStyle={{
              alignItems: 'center',
              justifyContent: 'center',
            }}
            centerContent
            pinchGestureEnabled={false}
            snapToInterval={ITEM_HEIGHT}
            snapToAlignment=&quot;start&quot;
            onScroll={scrollHandler}
            scrollEventThrottle={16}&gt;
            {['spacer', ...data, 'spacer'].map((item, idx) =&gt; (
              &lt;SpinnerItem
                key={idx}
                idx={idx}
                scrollY={scrollY}
                label={item === 'spacer' ? '' : item}
              /&gt;
            ))}
          &lt;/Animated.ScrollView&gt;
        &lt;/View&gt;
      &lt;/SafeAreaView&gt;
    );
  }
  
  const styles = StyleSheet.create({
    container: {
      flexDirection: 'row',
      alignItems: 'center',
      justifyContent: 'center',
      alignSelf: 'center',
      backgroundColor: '#ecf0f1',
      height: ITEM_HEIGHT * 3,
      width: ITEM_WIDTH,
      overflow: 'hidden',
    },
    label: {
      textAlignVertical: 'center',
      textAlign: 'center',
      color: 'red',
      fontSize: FONT_SIZE,
      fontWeight: '700',
    },
  });
  
  </code></pre>