react-flip-toolkit
react-flip-toolkit copied to clipboard
Problems with scroll in list-detail components
I know there are several issues about scrolling already resolved. But I think mine is a different case:
Scenario:
A component ItemsList and a component ItemView, conditionally shown one or another depending on wether an item is selected.
Mobile screen: from the second item some scroll is always needed to reach it.
Content of ItemView is larger than the screen height.
Problem:
For the first and second item (scroll = 0) there's no problem.
For the next items, there are two problems:
- The content of item view is shown initially scrolled, so the beginning of the content is initially hidden. If I do a
window.scrollTo(0, 0)before or after the state change, the calculation of distance is higher than needed (the effect is the item comes from the hidden bottom of the page). - When I go back to the list, the scroll is not restored.
If you need a CodeSandbox I could prepare one.
I'm still facing this problem. I created a very small CodeSandbox here:
https://codesandbox.io/s/react-flip-toolkit-scroll-issue-d5csk
I have been reading the code and I'm pretty convinced the problem comes from the fact componentDidUpdate calls onFlipKeyUpdate (flip-toolkit package) which synchronously calls
var flippedElementPositionsAfterUpdate = getFlippedElementPositionsAfterUpdate({
element: containerEl,
portalKey: portalKey
});
Here, the bounding client rect is calculated from top of page, because the scroll is still at top before the useEffect was executed:
useEffect(() => !selected && window.scrollTo(0, scrollPosition), [
selected,
scrollPosition
]);
I'm trying to move the getFlippedElementPositionsAfterUpdate logic to somewhere I can control, so the animation only starts on demand and calculation is executed once the scroll was restored, but it's being a bit frustrating.
If anyone can give some clue or direction would be great.
I have been playing with handleEnterUpdateDelete, but flippedElementPositionsAfterUpdate are calculated at componentDidUpdate time.
I realized adding a setTimeout in Flipper componentDidUpdate:
componentDidUpdate(
prevProps: FlipperProps,
_prevState: any,
cachedData: FlippedElementPositionsBeforeUpdateReturnVals
) {
if (this.props.flipKey !== prevProps.flipKey && this.el) {
setTimeout(() => {
onFlipKeyUpdate(...)
})
}
}
makes the bounding client rect calculation right, but I'm sure that's a very dirty patch and also creates a small glitch on animation start.