react-infinite icon indicating copy to clipboard operation
react-infinite copied to clipboard

Is it possible to scroll to a specific element in the list programmatically?

Open lopno opened this issue 9 years ago • 10 comments

I am creating an application that has a list and a map using react-infinite. I would like to be able to scroll to a specific element in the list when clicking on a pin on the map.

Is this feature available in react-infinite?

Thanks for the awesome job you are doing on this component!

lopno avatar Nov 18 '15 15:11 lopno

This feature is not yet available - it wouldn't be too hard to add a scrollTop prop, but another prop might also be needed to control scroll animations.

garetht avatar Nov 30 '15 19:11 garetht

You can calculate the position of the element you want to scroll to and then use window.scrollTo(0, position);. I admit this is an ugly hack but it works.

HaNdTriX avatar Dec 14 '15 14:12 HaNdTriX

@Iopno- you may want to check out react-virtualized if you're still looking for a virtualized list that supports a programmatic scroll-to-index property.

bvaughn avatar Dec 23 '15 23:12 bvaughn

I implemented something like this on another project of mine. Let me see if I can build out a more generic solution that we could use in infinite.

On Wed, Dec 23, 2015, 18:21 Brian Vaughn [email protected] wrote:

@Iopno- you may want to check out react-virtualized https://github.com/bvaughn/react-virtualized if you're still looking for a virtualized list that supports a programmatic scroll-to-index property.

— Reply to this email directly or view it on GitHub https://github.com/seatgeek/react-infinite/issues/110#issuecomment-167007862 .

jayfunk avatar Dec 23 '15 23:12 jayfunk

Has anyone figured this out? We want to add keyboard up/down buttons which would be far easier to implement if something like this existed.

Like a scrollToIndex method on the component.

nemo avatar Mar 28 '16 21:03 nemo

Yeah, I'd also be interested in way to scroll to an element programmatically. I found react-virtualized too complicated to use, this component is really easy to integrate !

deviantony avatar Apr 01 '16 06:04 deviantony

@deviantony @nemo

Here's some copy pasta. May it serve you well:

import React from 'react';
import { findDOMNode } from 'react-dom'
import Infinite from 'react-infinite'
import key from 'mousetrap'
import SearchItem from './SearchItem'

class SearchList extends React.Component {

    constructor(props) {
        super(props)
        this.items = []
    }

    componentDidMount() {
        key.bind('up', e => {
            let prevItem = document.activeElement.tabIndex - 1
            findDOMNode(this.items[prevItem] ? this.items[prevItem] : this.items[this.items.length - 1]).focus()
        })
        key.bind('down', e => {
            const nextItem = this.items[document.activeElement.tabIndex + 1]
            findDOMNode(nextItem ? nextItem : this.items[0]).focus()
        })
    }

    render() {
        const { results } = this.props

        return <Infinite useWindowAsScrollContainer={true} elementHeight={31}>
            {results.map((item, k) => {
                return <SearchItem key={k}
                                   tabIndex={k}
                                   ref={ref => this.items[k] = ref}
                                   item={item}/>
            })}
        </Infinite>
    }
}

export default SearchList;

nightwolfz avatar Apr 11 '16 03:04 nightwolfz

@garetht I tried to set scrollTop=1000000 on the the list container but it doesn't seem to scroll down all the way. It always seems to only be able to scroll to top of the spacer element.

geekyme avatar May 05 '16 11:05 geekyme

Does a method scrollTo is still planned ?

Karath51 avatar Oct 17 '16 14:10 Karath51

If anyone is looking to build this themselves, one solution I came up with for my app has been to have my main/container component set the scrollTo position itself for it's corresponding presentation component.

Here's an example:

// ListContainer.jsx 

class ListContainer extends Component {
  ...
  componentDidUpdate(prevProps) {
    // If we're targeting a specific item and we know that it's been
    // loaded in, scroll to that item.
    if (prevProps.pagination.initialLoad) {
      this._scrollListToItem(this.props.itemId);
    }
  }

  // Scroll the list div to the correct position based off
  // of index. The variable listItemHeight may change in the future
  _scrollListToItem = (id) => {
    const itemIdx = this.props.items.findIndex((i) => i && (i.id === id));
    // listItemHeight is the total height of a cell in the list
    const listItemHeight = 60;
    $(".list").scrollTop(listItemIdx * listItemHeight);
  }
}


// List.jsx
const List = ({...}) => {
  const listItems = items.map((item, i) => <ListItem key={i} {...} />)
  return (
    <Infinite containerHeight={600} elementHeight={60} className="list">
      {listItems}
    </Infinite>
  );

Hope this helps someone

joerodrig avatar Feb 06 '17 17:02 joerodrig