DraggableFlatList onRef getting a wrong type with Typescript

1.3k Views Asked by At

I am using react-native-draggable-flatlist in ReactNative. I am interested in the ref to FlatList so that I can perform a scrollToIndex on it. Using the following code:

import React, {
    useEffect, createRef, useRef,
} from 'react'
import { ScrollView, FlatList } from 'react-native-gesture-handler'
import DraggableFlatList, {
    RenderItemParams, DragEndParams,
} from "react-native-draggable-flatlist"

export default function TasksList(props: Props) {

    const ref = createRef<DraggableFlatList<ITask>>()
    const flatListRef = useRef<FlatList<ITask> | null>(null)

    return (
        <DraggableFlatList
            ref={ref}
            onRef={flatListRef}
...
    )
}

I get the following Typescript error:

Type 'MutableRefObject<(ComponentClass<FlatListProps & NativeViewGestureHandlerProps & RefAttributes, any> & { ...; }) | (FunctionComponent<...> & { ...; }) | null>' is not assignable to type '(ref: RefObject<FlatList>) => void'. Type 'MutableRefObject<(ComponentClass<FlatListProps & NativeViewGestureHandlerProps & RefAttributes, any> & { ...; }) | (FunctionComponent<...> & { ...; }) | null>' provides no match for the signature '(ref: RefObject<FlatList>): void'. The expected type comes from property 'onRef' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<DraggableFlatList> & Pick<Readonly<Modify<FlatListProps, { ...; } & Partial<...>>> & Readonly<...>, "ItemSeparatorComponent" | ... 150 more ... | "children"> & Partial<...> & Partial<...>'

How to fix the error so that I can use the ref/ onRef?

1

There are 1 best solutions below

1
On BEST ANSWER

I belive you're not getting what onRef prop is expecting to get here. If you look closely at the error it says along the lines something like that:

'MutableRefObject<FlatList<ITask> | null>' is not 
    assignable to type '(ref: RefObject<FlatList<ITask>>) => void'.

So, it clearly expects a function and not a RefObject. You may also refer to the source code to verify that:

    ...
    onRef?: (ref: React.RefObject<FlatList<T>>) => void;
    ...

It expects a function that will be given a ref of RefObject<FlatList<T>> type.

You may fix your code rewriting it as:

    ....
    const ref = createRef<DraggableFlatList<ITask>>()
    const flatListRef = useRef<React.RefObject<FlatList<ITask>> | null>(null)

    return (
        <DraggableFlatList
            ref={ref}
            onRef={(ref) => { flatListRef.current = ref }}

So inside flatListRef ref via it's current property you'll have access to the underlying FlatList ref.