Skip to content

Fix web useScrollViewOffset on wrapped scrolls#5861

Merged
szydlovsky merged 3 commits intomainfrom
@szydlovsky/scrollViewOffset-nested-scroll-fix
Apr 3, 2024
Merged

Fix web useScrollViewOffset on wrapped scrolls#5861
szydlovsky merged 3 commits intomainfrom
@szydlovsky/scrollViewOffset-nested-scroll-fix

Conversation

@szydlovsky
Copy link
Contributor

Summary

Inspired by #5790, it seems like scrolls can be wrapped in other views (by for example setting their onRefresh property), which makes refs to them point to the wrapping view, not them. Thus I add support for such situations to the useScrollViewOffset hook, which is our only hook that needs to access the component itself.

Test plan

Testing code
import React from 'react';
import {
  Text,
  Pressable,
  SafeAreaView,
  StyleSheet,
  Button,
  findNodeHandle,
} from 'react-native';
import Animated, {
  useAnimatedRef,
  useScrollViewOffset,
} from 'react-native-reanimated';

export default function App() {
  const animatedRef = useAnimatedRef<Animated.ScrollView>();
  const offset = useScrollViewOffset(animatedRef);
  const [refreshing, setRefreshing] = React.useState(false);

  function printOffset() {
    console.log('OFFSET VALUE');
    console.log(offset.value);
  }

  return (
    <SafeAreaView>
      <Button
        title="refresh"
        onPress={() => setRefreshing((oldState) => !oldState)}
      />
      <List
        animatedRef={animatedRef}
        printOffset={printOffset}
        refreshing={refreshing}
      />
    </SafeAreaView>
  );
}

const List = ({ animatedRef, printOffset, refreshing }) => {
  console.log('tag', findNodeHandle(animatedRef.current));
  return (
    <Animated.FlatList
      ref={animatedRef}
      refreshing={refreshing}
      style={{height: 600}}
      onRefresh={() => console.log('refreshing')}
      onViewableItemsChanged={() => {
        printOffset();
      }}
      data={[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]}
      renderItem={({ _, index }) => <Item onPress={printOffset} id={index} />}
    />
  );
};

const Item = ({ onPress, id }) => {
  return (
    <Pressable onPress={onPress} style={styles.pressable}>
      <Text>{id}</Text>
    </Pressable>
  );
};

const styles = StyleSheet.create({
  pressable: {
    padding: 40,
    justifyContent: 'center',
    alignItems: 'center',
    borderWidth: 1,
    borderColor: 'red',
    backgroundColor: 'white',
  },
});

@szydlovsky szydlovsky requested a review from tjzel April 3, 2024 14:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants