How to get the ref of the first element that's rendered with .map?

10,047

Maybe use a lookup table object or an array and store all the refs there by their index (or id).
Then when the component is mounted, you can trigger the focus event on the first one (or any other one by the key or id).

Simple example with inputs:

const videos = [
  { name: 'video 1' },
  { name: 'video 2' },
  { name: 'video 3' },
];

class App extends React.Component {
  constructor(props) {
    super(props);
    this.videoRefs = [];
  }

  componentDidMount() {
    this.videoRefs[0] && this.videoRefs[0].focus();
  }

  render() {
    return (
      <div >
        {
          videos.map((video, index) => (
            <input
              key={index}
              value={video.name}
              ref={ref => this.videoRefs[index] = ref}
            />
          ))
        }
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Share:
10,047
prasadmsvs
Author by

prasadmsvs

Working as a software engineer

Updated on June 18, 2022

Comments

  • prasadmsvs
    prasadmsvs almost 2 years

    I have a requirement to show thumbnails of videos(cards) in several rows and focus on the very first thumbnail. I did the display using Nested Map. The code basically iterates over a videos array and returns videos in several rows.

    How do we focus on the first element that renders? I think we need to get ref of the first element to focus. But how do we set ref here and reference it in another function?

    const CategoryGrid = props => {
      return (
        <HotKeys handlers={handlers}>
          <div className="grid-container">
            <p className="title"> {props.title.toUpperCase()} </p>
            <div className="grid">
              {
                props.videos.map((rowvideos,index) => {
                    var rowVideoArr = [];
                    rowvideos.map((video,key)=>{
                      rowVideoArr.push(<div  key={video.id} className="fleft card-container grow">
                        <Card key={video.id} title={video.name} background={video.thumbnailUrl}/>
                      </div>)
                    })
                    return(<div className="row" key={index}>{rowVideoArr}</div>)
                })
              }
            </div>
          </div>
        </HotKeys>
      );
    }
    
  • mluke
    mluke over 5 years
    Quite a sweet solution :)