react-infinite
react-infinite copied to clipboard
Is it possible to scroll to a specific element in the list programmatically?
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!
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.
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.
@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.
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 .
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.
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 @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;
@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.
Does a method scrollTo is still planned ?
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