The onScroll prop is ignored because it is overridden within this module.
onScroll is internally set to a Reanimated Event, and does not call the onScroll that is passed as a prop.
Is there any way we can get this to behave the same as a normal FlatList, and still do what is needed internally?
I have created a new issue because the original one #53, DID get fixed but a subsequent update broke it again.
Edit: typos
For my specific use case I ended up making this modification:
https://github.com/curiousdustin/react-native-draggable-flatlist/commit/9866d5413c70e0485ace31ebbc00a9369e5b9c94
This adds custom onScrollX and onScrollY props.
However, I am hoping there is a better way in which we can have it work as expected.
I feel there must be some way to map this.props.onScroll to be called within the event() block, but I just couldn't figure it out quickly.
We need to use reanimated's Event in order to get the native perf gains, and I'm pretty sure that doesn't support listeners, which is where the props.onScroll callback could go.
Would it work for you to use an onChange on the scroll offset? https://github.com/computerjazz/react-native-draggable-flatlist/blob/master/index.tsx#L164
something like:
<Animated.Code>
{() => onChange(scrollOffset, call([scrollOffset], ([scrollOffset]) => doJsThing(scrollOffset))))}
</Animated.Code>
That seems like it would fulfill the specific need I have, but it also still isn't great that onScroll can't function int he same way as a normal FlatList.
Are you saying that you would add a prop to DraggableFlatList? something like onScrollOffsetChange?
yep, it's not perfect, but since react-native-draggable-flatlist needs the onScroll event i'm not sure if that particular prop can be 1-1 with a normal flatlist.
I don't think I'd add another prop for this specific purpose, and I wouldn't want to add an unnecessary check/callback every frame since that could introduce perf issues, so I'd lean toward exposing the underlying Animated.Values in a friendlier way, at the expense of making developers get their feet wet with reanimated if they need that more advanced functionality.
ah yes, that makes more sense. Yeah, I think that is a good compromise.
@computerjazz , did you end up working on this at all?
I get the idea of what you're suggesting, but I'm not sure I grasp it enough to create a PR for it.
I had to create a fork with some hacky fixes for a delivery, but I'd love to get back on the main fork if possible.
I have not worked on it, but if all you need is a callback with the scrollOffset, you shouldn't need to fork -- you can grab the scrollOffset from the ref and then use it in an <Animated.Code> block:
import Animated from 'react-native-reanimated'
const { call, onChange } = Aniamted
class MyComponent {
scrollAnim = new Animated.Value(0)
onScroll = ([scrollOffset]) => console.log("on scroll", scrollOffset)
render() {
return (
<>
<DraggableFlatList
ref={ref => {
if (ref) {
this.scrollAnim = ref.scrollOffset
}
}}
// ...other props
/>
<Animated.Code>
{() => onChange(this.scrollAnim, call([this.scrollAnim], this.onScroll))}
</Animated.Code>
</>
)
}
}
see https://snack.expo.io/@computerjazz/swipetodelete-pkg for an example
Ok, sweet! Thanks so much for the quick example!
I'll give it a shot.
@computerjazz, just wanted to let you know that this example you provided was very useful and solved my use case. Thanks!
I will let you decide if you want to close this issue. In my mind, onScroll is still a pitfall for those looking to replace normal FlatLists with DraggableFlatLists. Maybe all that is needed is a note in the docs.
Glad to hear it! Yeah, I agree this is worth keeping open for now.
I'm also facing the issue with onScroll. Would there be any work around to determine the y offset(in which you'd get from onScroll prop normally) while scrolling?
Edit - above code works at the moment to get y offset thanks! though, animated events wouldn't cause too much perf issues right?
facing the same issue as well. Is there currently a timeline where this issue will be addressed? would love to be able to have something similar to onScroll without having to incorporate another library.
edit - was able to get it to work as well. here's a tweaked implementation of @computerjazz 's workaround using hooks
import Animated from 'react-native-reanimated'
const { call, onChange, useCode } = Animated
const [scrollAnim, setScrollAnim] = useState<AnimatedValue>(new Animated.Value(0))
const scrollableListRef = useRef<DraggableFlatList>(null)
const onScrollTest = ([scrollOffset]: readonly number[]) => console.log("on scroll", scrollOffset)
useEffect(() => {
if(scrollableListRef) setScrollAnim(scrollableListRef.current?.scrollOffset)
}, [scrollableListRef])
useCode(() => onChange(scrollAnim, call([scrollAnim], onScrollTest)), [scrollAnim])
return (
<DraggableFlatList
ref={scrollableListRef}
...other props
/>)
added onScrollOffsetChange prop in 2.3.1