scrollTo (Animated.ScrollView) scrollToOffest (Animated.FlatList) not working inside useEffect only when refreshing

Viewed 30

I'm attempting to use scrollTo or scrollToOffset from a Animated.ScrollView or from Animated.FlatList. The current flow I have is a modal in which opens images and on top of this images there is a empty ScrollView or FlatList just to animate. Everything is working fine, but if I want to start at a certain offset I can't seem to do it with the useEffect, although if I refresh the page, it will scroll to the offset I inserted.
This is the modal:

import React, { useState, useRef } from 'react';
import { Modal } from 'react-native';

// Gesture
import GestureRecognizer from 'react-native-swipe-gestures';

// Keyboard listener
// @ts-ignore
import KeyboardListener from 'react-native-keyboard-listener';

import { Stories } from '../../screens/StoriesTest/Stories';

interface StoriesModalProps {
  visible: boolean;
  setVisible: (value: boolean) => void;
  data: any;
}

export function StoriesModal({ visible, setVisible, data }: StoriesModalProps) {
  return (
    <GestureRecognizer
      style={{ flex: 1 }}
      onSwipeDown={() => {
        setVisible(false);
      }}
    >
      <Modal visible={visible}>{visible && <Stories stories={data} />}</Modal>
      <KeyboardListener onWillHide={() => {}} onWillShow={() => {}} />
    </GestureRecognizer>
  );
}

Which renders this stories:

import React, { useRef, createRef, useEffect } from 'react';
import {
  StyleSheet,
  View,
  ScrollView,
  Dimensions,
  Animated,
  FlatList,
  TouchableOpacity,
  VirtualizedList,
} from 'react-native';
import { Story } from './Story';
// import { StoryContainer } from 'react-native-stories-view';

interface StoriesProps {
  stories: any[];
}

const { width } = Dimensions.get('window');
const perspective = width;
const A = Math.atan(perspective / width / 2);

export function Stories({ stories }: StoriesProps) {
  // Animated
  const x = useRef(new Animated.Value(0)).current;

  // Reference
  const scrollViewRef = useRef();

  function handleGetStyle(index: number) {
    const offset = width * index;
    const inputRange = [offset - width, offset + width];
    const translateX = x.interpolate({
      inputRange,
      outputRange: [width / 2, -width / 2],
      extrapolate: 'clamp',
    });
    const rotateY = x.interpolate({
      inputRange,
      outputRange: [`${A}rad`, `-${A}rad`],
      extrapolate: 'clamp',
    });
    const translateX1 = x.interpolate({
      inputRange,
      outputRange: [width / 2, -width / 2],
      extrapolate: 'clamp',
    });

    return {
      ...StyleSheet.absoluteFillObject,
      transform: [{ perspective }, { translateX }, { rotateY }, { translateX: translateX1 }],
    };
  }

  useEffect(() => {
    // flatViewRef.current.scrollToOffset({ offset: width * 1, animated: false });
    if (scrollViewRef.current) {
      scrollViewRef.current.scrollTo({
        animated: false,
        x: width,
      });
    }
  }, []);

  return (
    <View style={styles.container}>
      {stories.map((story, index) => (
        <Animated.View style={handleGetStyle(index)} key={story.id}>
          <Story source={story.images} />
        </Animated.View>
      ))}

      <Animated.ScrollView
        ref={scrollViewRef}
        style={StyleSheet.absoluteFill}
        contentContainerStyle={{ width: width * stories.length }}
        showsVerticalScrollIndicator={false}
        scrollEventThrottle={16}
        snapToInterval={width}
        keyboardShouldPersistTaps="always"
        decelerationRate="fast"
        onScroll={Animated.event(
          [
            {
              nativeEvent: {
                contentOffset: { x },
              },
            },
          ],
          {
            useNativeDriver: true,
            listener: (event) => {
              // console.log(event.nativeEvent.contentOffset.x);
            },
          }
        )}
        horizontal
        data={[]}
        renderItem={() => <></>}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'black',
  },
});

The important part it the useEffect, it doesn't seem to perform the scrollTo when the component loads, only after the refresh.
I have searched several solutions but none of them seem to work or seem to be outdated.
this.scrollView.getNode is not a function

FlatList ref scrollToIndex is not a function

0 Answers
Related