Search code examples
javascriptreactjsscrollbaraudio-player

React. How to implement scrolling to active list item?


I build music player with search by the artist.

CODE SANDBOX

this how my SongsList component looks like:

    const SongsList = (props) => {
  const {
    loading,
    errorMessage,
    songsList,
    toggleActive,
    setToggleActive,
  } = props;
  return (
    <div className='player-list'>
      <div className='songs__list'>
        {loading && !errorMessage ? (
          <span>Loading...</span>
        ) : errorMessage ? (
          <div className='errorMessage'>{errorMessage}</div>
        ) : (
          songsList.map((song, index) => (
            <Song
              key={`${index}`}
              song={song}
              index={index}
              active={toggleActive === index}
              setToggleActive={() => {
                setToggleActive(index);
                // console.log(toggleActive);
              }}
            />
          ))
        )}
      </div>
    </div>
  );
};

Now I want to implement scrolling the SongList based on the activeSong position, so the active song will always change scrollbar position automatically to make it visible. What is the best way to do this?


Solution

  • I have resolved this using ref for a single song

      const SongsList = (props) => {
    

    ...

    const refs = songsList.reduce((song, value) => {
        song[value.id] = React.createRef();
        return song;
      }, {});
    

    ...

    and method call scrollIntoView

     const handleClick = id =>
        refs[id].current.scrollIntoView({
          behavior: "smooth",
          block: "start"
        });
    

    ...

    then in the Song.js component add this scroll() method

    const Song = ({...}) => {
      const scroll = () => (active ? scrollView(song.id) : undefined);
      useEffect(() => scroll());
    

    ...

    CodeSandbox finall resolve