reactjsreact-nativereact-hooks

React Native property 'ref' does not exist on type 'intrinsicattributes & flatlistprops<unknown>'.ts(2322)


This is my component:

import React, {memo} from 'react';
import {FlatList as RNFlatList, FlatListProps} from 'react-native';

// interface IFlatList<ItemT> extends FlatListProps<ItemT> {}

function FlatList<ItemT = any>(props: FlatListProps<ItemT>) {
  return (
    <RNFlatList
      {...props}
      nestedScrollEnabled
      showsVerticalScrollIndicator={false}
      showsHorizontalScrollIndicator={false}
      // Performance settings
      removeClippedSubviews={true} // Unmount components when outside of window
      initialNumToRender={20} // Reduce initial render amount
      maxToRenderPerBatch={20} // Reduce number in each render batch
      updateCellsBatchingPeriod={100} // Increase time between renders
      windowSize={10} // Reduce the window size
    />
  );
}

export default memo(FlatList);

when I call it:

<FlatList
    ref={flatListRef}
    // others props
/>

and it shows warning as title then I cannot use the ref.

I try to add

interface ClassAttributes<T> extends Attributes {
    ref?: LegacyRef<T> | undefined;
}

but I still can't find a solution to add it into props.

So where is the right way that I can customize my component and using all the default props of React Native's component?


Solution

  • I'm not sure about the practical use cases of a "Custom FlatList", because it doesn't affect the style at all. You already can style each item using renderItem, so there's no need for a "Custom FlatList". But if you REALLY want to, you should understand ref in React itself first before writing any custom component, then get to know useRef, useImperativeHandle. You have to pass the ref to FlatList itself using forwardRef.

    Here's an example:

    import React, { forwardRef, useRef } from 'react';
    import {
      FlatList,
      FlatListProps,
      Text,
      TouchableOpacity,
      View,
    } from 'react-native';
    
    interface CustomFlatListProps<T> extends FlatListProps<T> {}
    
    export const CustomFlatList = forwardRef<FlatList, CustomFlatListProps<any>>(
      (props, ref) => {
        return <FlatList ref={ref} {...props} />;
      }
    );
    
    interface ItemData {
      id: string;
      title: string;
    }
    
    const demoData: ItemData[] = [
      { id: '1', title: 'something 1' },
      { id: '2', title: 'something 2' },
      { id: '3', title: 'something 3' },
    ];
    
    export function DemoUsingCustomFlatList() {
      const flatListRef = useRef<FlatList>(null);
    
      function _renderItem({ item }: { item: ItemData }) {
        return <Text>{item.title}</Text>;
      }
    
      return (
        <View>
          <CustomFlatList
            ref={flatListRef}
            data={demoData}
            renderItem={_renderItem}
            keyExtractor={(item) => item.id}
          />
    
          <TouchableOpacity onPress={() => flatListRef.current?.scrollToEnd()}>
            <Text>Click to scroll to end</Text>
          </TouchableOpacity>
        </View>
      );
    }