Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SectionList misses scrollTo* methods #13151

Closed
nihgwu opened this issue Mar 26, 2017 · 32 comments
Closed

SectionList misses scrollTo* methods #13151

nihgwu opened this issue Mar 26, 2017 · 32 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@nihgwu
Copy link
Contributor

nihgwu commented Mar 26, 2017

I'm planning to switch from ListView to SectionList, but find that I can't perform any scrollTo* methods, they are defined in VirtualizedList but not in VirtualizedSectionList. At least scrollToOffset should be implemented.

I'd like to send a PR, but I'm afraid to break the docs, and I don't know whether should we implement scrollToIndex and scrollToItem as they are different from FlatList

Perhaps a new method scrollToSection could be added too, it's a common use case in a contact list

@sahrens

@sahrens
Copy link
Contributor

sahrens commented Mar 26, 2017

Yeah I punted on this but I agree it's important. Maybe scrollToIndexInSection({sectionKey: string, index: number})?

@nihgwu
Copy link
Contributor Author

nihgwu commented Mar 26, 2017

IMO, scrollTo* is a bit complex, especially the scrollToOffset({ animated: boolean?, offset: number }), now that it receives a object, what about simplify them to a single method scrollTo(params) where the params is in a shape of { animated: boolean?, offset: number?, index: number?, item: object?, sectionKey: string? } or scrollToOffset(offset: number, animated: boolean?)

And the renderItem(info: {item: object, index: number}) -> renderItem(item: object, index: number)

Those are just some of my thoughts when I'm trying to switch from ListView to SectionList

Thanks for your great effort to create such a wonderful component

@sahrens
Copy link
Contributor

sahrens commented Mar 26, 2017

I appreciate the input, but here is the reasoning:

scrollTo* is more explicit and makes the API more clearly self documenting and simpler to flow-type, especially with composition.

renderItem(info: {...}) makes it easier to pull out just the info you care about in an order-independent way, and gives us the option value to add more data in the future in a backwards compatible way.

@jpshelley
Copy link
Contributor

Has anyone started work on this? Don't want to duplicate efforts if so, otherwise I may have time to try it out. Although I'll defer to @sahrens if he already has thoughts on how to implement 😄

@sahrens
Copy link
Contributor

sahrens commented Mar 31, 2017

No one is working on it to my knowledge so a PR would be appreciated :)

Just need to figure out the right API since we need to account for sections. I'll let you take a stab at it and we can iterate in review, just cc me in the PR summary.

@nihgwu
Copy link
Contributor Author

nihgwu commented Mar 31, 2017

@jpshelley 👍

@mediaxtend
Copy link

@jpshelley, can you have a look to sticky section header support too? ;)

@jpshelley
Copy link
Contributor

@mediaxtend PRs get merged faster if broken into smaller 'sections', so you should probably submit a new issue for it.

@sahrens
Copy link
Contributor

sahrens commented Mar 31, 2017

Sticky headers are already in master.

@mediaxtend
Copy link

@jpshelley, got it for the next time! 😇
@sahrens, I thought they were not because I've read:

Sticky headers are not yet supported.

(https://github.com/facebook/react-native/blob/master/Libraries/Lists/SectionList.js#L111)

If you need sticky section header support, use ListView for now.

(https://github.com/facebook/react-native/blob/master/Libraries/Lists/SectionList.js#L149)

I have to test this.

@sahrens
Copy link
Contributor

sahrens commented Apr 1, 2017

Oh ha, forgot to update that comment!

@jpshelley
Copy link
Contributor

@sahrens I started a branch on this work here and wanted to get your (and others) thoughts on the API.
https://github.com/jpshelley/react-native/tree/SectionList-AddScrollToSupport

I'm basically just making a wrapper call to the underlying VirtualizedSectionList which calls the VirtualizedList. The scrollToEnd is a fairly trivial function to show the implementation, with scrollToIndexInSection a suitable next candidate to add imo and which could take a little bit more work.

  • Thoughts on the implementation?
  • Thoughts on how many methods we should add before submitting a PR (scrollToEnd, scrollToIndexInSection, etc like the FlatList)?

@sahrens
Copy link
Contributor

sahrens commented Apr 4, 2017

An internal client needed scrollToIndexAtSection support so I already added it in master (as scrollToLocation - maybe naming could be better, what do you think?). I think scrollToEnd can be done via getScrollResponder so not a big deal, but if you want to put up a PR for it I'll take a look.

@jpshelley
Copy link
Contributor

We might end up using https://github.com/expo/react-native-invertible-scroll-view for our ScrollComponent for what I'm working on anyways so good timing 😄 We can ditch the branch I created in favor of yours and probably close this issue if @nihgwu agrees

@postalPain
Copy link

postalPain commented May 3, 2017

The 44-th version has been released but scrollTo method is not added :(
When are you going to release it?

@sahrens
Copy link
Contributor

sahrens commented May 3, 2017

You can browse the code by branch here: https://github.com/facebook/react-native/branches

Looks like 0.45 hasn't been cut yet, so you can look at master and see scrollToLocation has been added:

https://github.com/facebook/react-native/blob/master/Libraries/Lists/SectionList.js

So it should be in v0.45 which will ship the beginning of next month since we're on a monthly release schedule.

You can run off master if you want, just update your package.json.

@stanonyime
Copy link

Any tip on how to use it? Do you pass it as a prop to Sectionlist list. Is it like:

<SectionList scrollToEnd={{} ...props />

or as a ref?

@namqdam
Copy link

namqdam commented May 20, 2017

@sahrens Thank you, I've found the method scrollToLocation, and it's working for a normal SectionList. Because I use Animated.event with nativeDriver when onScroll so I need to wrap this SectionList with createAnimatedComponent to be AnimatedSectionList. The problem appears that there's no method scrollToLocation for AnimatedSectionList. Please support this method for createAnimatedComponent(SectionList).

@sahrens
Copy link
Contributor

sahrens commented May 20, 2017

It's a method, so call it on the ref.

createAnimatedComponent exposes a getNode Method which provides access to scrollToLocation and any other methods on the wrapped component.

@sahrens sahrens closed this as completed May 20, 2017
@RUIFERNANDE5
Copy link

RUIFERNANDE5 commented Jun 19, 2017

@sahrens Version 0.45 is already up and scrollToLocation is documented, but I can't really find an example. Would be awesome if you could give me a hint how can I get the index in renderSectionHeader and scroll to that section index?

Thanks in advance
EDIT:

I was able to use it:

scrollView.scrollToLocation({
         animated: true,
         sectionIndex: 3,
         itemIndex: 0,
         viewOffset: 28 // height of section header
})

@facuescobar
Copy link

facuescobar commented Jun 23, 2017

@RUIFERNANDE5
how your component looks like? can you post your example of how did you get this feature working?

I am trying to get this feature working too, but I can't find any example.

UPDATE: I just found that ReactNative 0.44 doesn't have this feature in SectionList...thanks anyway!

@manjeets12
Copy link

@RUIFERNANDE5 I tried something similar but it doesn't scrolling to desired position

this.tableList.scrollToLocation({animated: true,sectionIndex:0, itemIndex: 5, viewPosition:0.5});
my sectionslist looks something like this

<SectionList
                  ref={(ref) => { this.tableList = ref; }}
                  renderItem={this.renderItem.bind(this)}
                  renderSectionHeader={this.renderSectionHeader.bind(this)}
                  getItemLayout={this.getItemLayout.bind(this)}
                  sections={tables}
                  stickySectionHeadersEnabled={true}
                  keyExtractor={this.keyExtractor.bind(this)}
                />

@ghost
Copy link

ghost commented Jul 26, 2017

+1 for scrollTo or scrollToOffset

is anybody working on it ?

@steobrien
Copy link

steobrien commented Oct 18, 2017

[Update 2018-04-13: this workaround apparently works on iOS, but not Android]

A workaround in the absence of these methods is to work back to the VirtualizedList and directly access them there. This requires using underscored, undocumented methods and so should only be used in a pinch.

For example:

//…

componentDidMount() {
  this.refs.list._wrapperListRef._listRef.scrollToOffset({offset: 0})
}

//…

<SectionList ref="list" {…otherProps} />

//…

@AndreyMalykhin
Copy link

+1 for scrollTo()

@PackZhang
Copy link

@manjeets12 Maybe your getItemLayout method is not correct, you can try remove that

@jayesbe
Copy link

jayesbe commented Apr 5, 2018

spent days on this.

scrollToLocation does not work even with getItemLayout specified until the rendering of the list is completed. The only way I got it to work is by wrapping the scrollToLocation in a setTimeout of 10 seconds. (dev / android)

Even with a 5 second timeout, it would still only scroll partially towards the correct position.

Is there anyway to know when the list is rendered and ready ?

@sahrens
Copy link
Contributor

sahrens commented Apr 6, 2018

You could add an onLayout callback to your last item and do the scrollTo once that fires, although something else funky might be going on if a 5 second timeout doesn't work. Did you try setting initialScrollIndex?

@jayesbe
Copy link

jayesbe commented Apr 6, 2018

Thanks @sahrens will give onLayout a try. though the list always initial renders as empty so onLayout will not fire again once the data is updated.

I tried initialScrollIndex and it results in only the very first section header being rendered. I tried with initialScrollIndex > 0 and it had the same result for any value I tried.. never tried with 0 though.

@jayesbe
Copy link

jayesbe commented Apr 6, 2018

onLayout doesn't work.

The logs are interesting. I subscribe to an event in each list item and I log each subscription. The list size is small ~100 items. I can see that the initial viewable items render really quick ~7 items with the initial render set to 15. I can see that onLayout fires after about 30 subscription. I trigger the scrollToLocation onLayout to the middle index (i = 50) however it doesn't scroll to that location. Stops around the 30th.

If I wait about 5-6 seconds.. I finally see a total of 100 subscriptions logged. So the scrollToLocation only works after componentDidMount has been applied to item you need to scroll to. I subscribe to the event in the componentDidMount of the list item component.

@JeremyBradshaw7
Copy link

@steobrien your solution works on ios but doesn't seem to on android, at least with my preliminary testing.

@steobrien
Copy link

Thanks @JeremyBradshaw7, I've updated the comment.

@facebook facebook locked as resolved and limited conversation to collaborators May 24, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests