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

React-redux-router reducer change causes elementScroller to restore node #5

Open
Mystify76 opened this issue Oct 1, 2019 · 2 comments

Comments

@Mystify76
Copy link

I have a page in my site that has an element scroller attached to it. Everything works great and when the page refreshes or navigates, everything works exactly as it should.

However, on my page, if I do a call to update a reducer, it causes an app wide state change.

In ElementScroller.js on line 19, there is a componentDidUpdate function for the element.

componentDidUpdate(prevProps) { this._unregister(prevProps); this._register(); }

As a result, when the reducer updates, this code is called and causes the element's scroll position to be reset. So if the page "started" at the top, and I scroll down the page and do something to update a reducer, the above code will cause the element to scroll to the top of the page.

I commented out the did update and the problem went away, but I am not sure if this will have any side effects elsewhere.

Is there anyway it can be updated so that it doesn't restore the node scroll position on did update due to a reducer change?

@trevorr
Copy link
Owner

trevorr commented Oct 1, 2019

That's a good question. I'll need a little time to look into it and remember why it is the way it is. I imagine that lifecycle hook is necessary for some cases, but I can easily believe it didn't anticipate others.

@Mystify76
Copy link
Author

Mystify76 commented Oct 10, 2019

Ok, a little more info.... after commenting out that did update, I found that when changing routes from within the app, the scroll manager stopped scrolling to the top.... apparently, that did update was responsible for that.

So, in my use case, and I am not sure if this is true for everyone, I only wanted it to "restore" the scroll position on a page change.... so, in the ScrollManager.js constructor, right above the history.listen, I put this:

this._historyChanged = true;

then, directly inside the the history.listener call back, I put the same thing:

this._historyChanged = true;
this._unlisten = history.listen((location, action) => {
this._historyChanged = true;
this._savePositions();

Then, in the _restoreNode and the _restoreWindow functions I added this._historyChanged = false; to the first line of the functions.

in ElementScroller.js, I re-added the componentDidUpdate function and modified it to be like this:

componentDidUpdate(prevProps) {
const { manager } = this.props;
if(!manager._historyChanged) return;
this._unregister(prevProps);
this._register();
}

Now, the pages restore the scroll on internal route changes, on page reloads, but NOT on reducer changes because the route didn't change.

I can't think of any other time we would want the scroll position to restore outside of the route/page reload or change, so this works for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants