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