React-Hooks- How to assign an unique "ref" to every rendered item in a renderItem using FlatList?

Viewed 656

I am trying to convert a class component to a function component and struggling with assigning the refs to each rendered item in a Flatlist.

This is the original class component.



... 

constructor(props) {
    super(props);
    this.cellRefs = {};
  }

....


_renderItem = ({ item }) => {
    return (
      <Item
        ref={ref => {
          this.cellRefs[item.id] = ref;
        }}
        {...item}
      />
    );
  };

...

2 Answers

Assuming both your Item and the component rendering the FlatList need to be functional components, you need to take care of 2 things

  • Add dynamic refs to each Item component
  • Make sure that the Item component uses useImperativeHandle with forwardRef to expose functions
const App = () => {
   const cellRefs = useRef({}) // Adding an object as we need more than one ref
   const _renderItem = ({ item }) => {
    return (
      <Item
        ref={ref => {
          cellRefs.current[item.id] = ref;
        }}
        {...item}
      />
    );
  };
  ....
}

Post that you need to change your Item component like

const Item = React.forwardRef((props, ref) => {
   ...
   const handleClick = () => {};
   useImperativeHandle(ref, () => ({
        // values that need to accessible by component using ref, Ex
        handleClick,

   }))
   ...
})

P.S. If Item is not a functional component, you can avoid the second step

do something like that (from react doc)

   function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}
Related