How to scroll a React page when it loads? Unicorn Meta Zoo #1: Why another podcast? Announcing the arrival of Valued Associate #679: Cesar Manara Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!How to scroll HTML page to given anchor?Loop inside React JSXReact-router urls don't work when refreshing or writing manuallyReact js onClick can't pass value to methodWhat's the difference between “super()” and “super(props)” in React when using es6 classes?Can you force a React component to rerender without calling setState?What is the difference between using constructor vs getInitialState in React / React Native?What do these three dots in React do?Programmatically navigate using react routerWhat is the difference between React Native and React?React-select sometimes doesn't display the options in the dropdown menu on async search

Is Electric Central Heating worth it if using Solar Panels?

Is it acceptable to use working hours to read general interest books?

Check if a string is entirely made of the same substring

Mistake in years of experience in resume?

Will I lose my paid in full property

Is Diceware more secure than a long passphrase?

Why did C use the -> operator instead of reusing the . operator?

Why is an operator the quantum mechanical analogue of an observable?

Seek and ye shall find

Could Neutrino technically as side-effect, incentivize centralization of the bitcoin network?

How to open locks without disable device?

What *exactly* is electrical current, voltage, and resistance?

My admission is revoked after accepting the admission offer

Does Feeblemind produce an ongoing magical effect that can be dispelled?

Can I criticise the more senior developers around me for not writing clean code?

What is this word supposed to be?

Split coins into combinations of different denominations

Is Bran literally the world's memory?

Has a Nobel Peace laureate ever been accused of war crimes?

PIC mathematical operations weird problem

What do you call the part of a novel that is not dialog?

Do you need a weapon for Thunderous Smite, and the other 'Smite' spells?

Book with legacy programming code on a space ship that the main character hacks to escape

Would reducing the reference voltage of an ADC have any effect on accuracy?



How to scroll a React page when it loads?



Unicorn Meta Zoo #1: Why another podcast?
Announcing the arrival of Valued Associate #679: Cesar Manara
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!How to scroll HTML page to given anchor?Loop inside React JSXReact-router urls don't work when refreshing or writing manuallyReact js onClick can't pass value to methodWhat's the difference between “super()” and “super(props)” in React when using es6 classes?Can you force a React component to rerender without calling setState?What is the difference between using constructor vs getInitialState in React / React Native?What do these three dots in React do?Programmatically navigate using react routerWhat is the difference between React Native and React?React-select sometimes doesn't display the options in the dropdown menu on async search



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








6















I want to pass a value as the hash in the url (myapp.com#somevalue) and have the page scroll to that item when the page loads - exactly the behavior of using a hash fragment since the beginning of the internet. I tried using scrollIntoView but that fails on iOS. Then I tried just unsetting/setting window.location.hash but there seems to be a race condition. It only works when the delay is more than 600ms.



I would like a more solid solution and don't want to introduce an unnecessary delay. When the delay is too short, it appears to scroll to the desired item but then scrolls to the top of the page. You won't see the effect on this demo but it happens in my actual app https://codesandbox.io/s/pjok544nrx line 75



 componentDidMount() 
let self = this;

let updateSearchControl = hash =>
let selectedOption = self.state.searchOptions.filter(
option => option.value === hash
)[0];
if (selectedOption)
// this doesn't work with Safari on iOS
// document.getElementById(hash).scrollIntoView(true);

// this works if delay is 900 but not 500 ms
setTimeout(() =>
// unset and set the hash to trigger scrolling to target
window.location.hash = null;
window.location.hash = hash;
// scroll back by the height of the Search box
window.scrollBy(
0,
-document.getElementsByClassName("heading")[0].clientHeight
);
, 900);
else if (hash)
this.searchRef.current.select.focus();

;

// Get the hash
// I want this to work as a Google Apps Script too which runs in
// an iframe and has a special way to get the hash
if (!!window["google"])
let updateHash = location =>
updateSearchControl(location.hash);
;
eval("google.script.url.getLocation(updateHash)");
else
let hash = window.location.hash.slice(1);
updateSearchControl(hash);




EDIT: I tracked down the line of React that re-renders the page and consequently resets the scroll position after it already scrolled where I told it to go in componentDidMount(). It's this one.
style[styleName] = styleValue; At the time the page is re-rendered it is setting the width style property of the inputbox component of the react-select box component. The stack trace right before it does this looks like



(anonymous) @ VM38319:1
setValueForStyles @ react-dom.development.js:6426
updateDOMProperties @ react-dom.development.js:7587
updateProperties @ react-dom.development.js:7953
commitUpdate @ react-dom.development.js:8797
commitWork @ react-dom.development.js:17915
commitAllHostEffects @ react-dom.development.js:18634
callCallback @ react-dom.development.js:149
invokeGuardedCallbackDev @ react-dom.development.js:199
invokeGuardedCallback @ react-dom.development.js:256
commitRoot @ react-dom.development.js:18867
(anonymous) @ react-dom.development.js:20372
unstable_runWithPriority @ scheduler.development.js:255
completeRoot @ react-dom.development.js:20371
performWorkOnRoot @ react-dom.development.js:20300
performWork @ react-dom.development.js:20208
performSyncWork @ react-dom.development.js:20182
requestWork @ react-dom.development.js:20051
scheduleWork @ react-dom.development.js:19865
scheduleRootUpdate @ react-dom.development.js:20526
updateContainerAtExpirationTime @ react-dom.development.js:20554
updateContainer @ react-dom.development.js:20611
ReactRoot.render @ react-dom.development.js:20907
(anonymous) @ react-dom.development.js:21044
unbatchedUpdates @ react-dom.development.js:20413
legacyRenderSubtreeIntoContainer @ react-dom.development.js:21040
render @ react-dom.development.js:21109
(anonymous) @ questionsPageIndex.jsx:10
./src/client/questionsPageIndex.jsx @ index.html:673
__webpack_require__ @ index.html:32
(anonymous) @ index.html:96
(anonymous) @ index.html:99


I don't know where to move my instruction to scroll the page. It has to happen after these styles are set which is happening after componentDidMount().



EDIT: I need to better clarify exactly what I need this to do. Apologies for not doing that before.



Must haves



This has to work on all common desktop and mobile devices.



When the page loads there could be three situations depending on what query is provided in the url after the #:



  • 1) no query was provided - nothing happens

  • 2) a valid query was provided - the page scrolls instantly to the desired anchor and the page's title changes to the label of the option

  • 3) an invalid query was provided - the query is entered into the search box, the search box is focused and the menu opens with options limited by the provided query as if they had been typed in. The cursor is located in the search box at the end of the query so the user can modify the query.

A valid query is one that matches the value of one of the options. An invalid query is one that doesn't.



The browser back and forward buttons should move the scroll position accordingly.



Any time an option is chosen from the Search box the page should scroll instantly to that anchor, the query should clear returning to the placeholder "Search...", the url should update, and the document's title should change to the option's label.



Optional but would be great



After making a selection the menu closes and the query goes back to "Search...", and either



  • the Search box retains the focus so the user can begin typing another query. The next time it is clicked, the menu opens, and the Searchbox query from before the selection, the menu's filter and the menu scroll position are restored (most preferred), or

  • the Search box loses focus. The next time it is focused, the menu opens, and the Search box query from before the selection, the menu's filter and the menu scroll position are restored (preferred), or

  • the Search box retains the focus so the user can begin typing another query. The prior query and menu scroll position are lost.









share|improve this question



















  • 1





    possible solution - stackoverflow.com/questions/3163615/…

    – fard
    Mar 22 at 15:47











  • maybe useEffect is worth to give it a try. as I understand useEffect will run after rendering submitted to the screen and at that time the element is ready to scroll to

    – duc mai
    Mar 29 at 18:29

















6















I want to pass a value as the hash in the url (myapp.com#somevalue) and have the page scroll to that item when the page loads - exactly the behavior of using a hash fragment since the beginning of the internet. I tried using scrollIntoView but that fails on iOS. Then I tried just unsetting/setting window.location.hash but there seems to be a race condition. It only works when the delay is more than 600ms.



I would like a more solid solution and don't want to introduce an unnecessary delay. When the delay is too short, it appears to scroll to the desired item but then scrolls to the top of the page. You won't see the effect on this demo but it happens in my actual app https://codesandbox.io/s/pjok544nrx line 75



 componentDidMount() 
let self = this;

let updateSearchControl = hash =>
let selectedOption = self.state.searchOptions.filter(
option => option.value === hash
)[0];
if (selectedOption)
// this doesn't work with Safari on iOS
// document.getElementById(hash).scrollIntoView(true);

// this works if delay is 900 but not 500 ms
setTimeout(() =>
// unset and set the hash to trigger scrolling to target
window.location.hash = null;
window.location.hash = hash;
// scroll back by the height of the Search box
window.scrollBy(
0,
-document.getElementsByClassName("heading")[0].clientHeight
);
, 900);
else if (hash)
this.searchRef.current.select.focus();

;

// Get the hash
// I want this to work as a Google Apps Script too which runs in
// an iframe and has a special way to get the hash
if (!!window["google"])
let updateHash = location =>
updateSearchControl(location.hash);
;
eval("google.script.url.getLocation(updateHash)");
else
let hash = window.location.hash.slice(1);
updateSearchControl(hash);




EDIT: I tracked down the line of React that re-renders the page and consequently resets the scroll position after it already scrolled where I told it to go in componentDidMount(). It's this one.
style[styleName] = styleValue; At the time the page is re-rendered it is setting the width style property of the inputbox component of the react-select box component. The stack trace right before it does this looks like



(anonymous) @ VM38319:1
setValueForStyles @ react-dom.development.js:6426
updateDOMProperties @ react-dom.development.js:7587
updateProperties @ react-dom.development.js:7953
commitUpdate @ react-dom.development.js:8797
commitWork @ react-dom.development.js:17915
commitAllHostEffects @ react-dom.development.js:18634
callCallback @ react-dom.development.js:149
invokeGuardedCallbackDev @ react-dom.development.js:199
invokeGuardedCallback @ react-dom.development.js:256
commitRoot @ react-dom.development.js:18867
(anonymous) @ react-dom.development.js:20372
unstable_runWithPriority @ scheduler.development.js:255
completeRoot @ react-dom.development.js:20371
performWorkOnRoot @ react-dom.development.js:20300
performWork @ react-dom.development.js:20208
performSyncWork @ react-dom.development.js:20182
requestWork @ react-dom.development.js:20051
scheduleWork @ react-dom.development.js:19865
scheduleRootUpdate @ react-dom.development.js:20526
updateContainerAtExpirationTime @ react-dom.development.js:20554
updateContainer @ react-dom.development.js:20611
ReactRoot.render @ react-dom.development.js:20907
(anonymous) @ react-dom.development.js:21044
unbatchedUpdates @ react-dom.development.js:20413
legacyRenderSubtreeIntoContainer @ react-dom.development.js:21040
render @ react-dom.development.js:21109
(anonymous) @ questionsPageIndex.jsx:10
./src/client/questionsPageIndex.jsx @ index.html:673
__webpack_require__ @ index.html:32
(anonymous) @ index.html:96
(anonymous) @ index.html:99


I don't know where to move my instruction to scroll the page. It has to happen after these styles are set which is happening after componentDidMount().



EDIT: I need to better clarify exactly what I need this to do. Apologies for not doing that before.



Must haves



This has to work on all common desktop and mobile devices.



When the page loads there could be three situations depending on what query is provided in the url after the #:



  • 1) no query was provided - nothing happens

  • 2) a valid query was provided - the page scrolls instantly to the desired anchor and the page's title changes to the label of the option

  • 3) an invalid query was provided - the query is entered into the search box, the search box is focused and the menu opens with options limited by the provided query as if they had been typed in. The cursor is located in the search box at the end of the query so the user can modify the query.

A valid query is one that matches the value of one of the options. An invalid query is one that doesn't.



The browser back and forward buttons should move the scroll position accordingly.



Any time an option is chosen from the Search box the page should scroll instantly to that anchor, the query should clear returning to the placeholder "Search...", the url should update, and the document's title should change to the option's label.



Optional but would be great



After making a selection the menu closes and the query goes back to "Search...", and either



  • the Search box retains the focus so the user can begin typing another query. The next time it is clicked, the menu opens, and the Searchbox query from before the selection, the menu's filter and the menu scroll position are restored (most preferred), or

  • the Search box loses focus. The next time it is focused, the menu opens, and the Search box query from before the selection, the menu's filter and the menu scroll position are restored (preferred), or

  • the Search box retains the focus so the user can begin typing another query. The prior query and menu scroll position are lost.









share|improve this question



















  • 1





    possible solution - stackoverflow.com/questions/3163615/…

    – fard
    Mar 22 at 15:47











  • maybe useEffect is worth to give it a try. as I understand useEffect will run after rendering submitted to the screen and at that time the element is ready to scroll to

    – duc mai
    Mar 29 at 18:29













6












6








6


1






I want to pass a value as the hash in the url (myapp.com#somevalue) and have the page scroll to that item when the page loads - exactly the behavior of using a hash fragment since the beginning of the internet. I tried using scrollIntoView but that fails on iOS. Then I tried just unsetting/setting window.location.hash but there seems to be a race condition. It only works when the delay is more than 600ms.



I would like a more solid solution and don't want to introduce an unnecessary delay. When the delay is too short, it appears to scroll to the desired item but then scrolls to the top of the page. You won't see the effect on this demo but it happens in my actual app https://codesandbox.io/s/pjok544nrx line 75



 componentDidMount() 
let self = this;

let updateSearchControl = hash =>
let selectedOption = self.state.searchOptions.filter(
option => option.value === hash
)[0];
if (selectedOption)
// this doesn't work with Safari on iOS
// document.getElementById(hash).scrollIntoView(true);

// this works if delay is 900 but not 500 ms
setTimeout(() =>
// unset and set the hash to trigger scrolling to target
window.location.hash = null;
window.location.hash = hash;
// scroll back by the height of the Search box
window.scrollBy(
0,
-document.getElementsByClassName("heading")[0].clientHeight
);
, 900);
else if (hash)
this.searchRef.current.select.focus();

;

// Get the hash
// I want this to work as a Google Apps Script too which runs in
// an iframe and has a special way to get the hash
if (!!window["google"])
let updateHash = location =>
updateSearchControl(location.hash);
;
eval("google.script.url.getLocation(updateHash)");
else
let hash = window.location.hash.slice(1);
updateSearchControl(hash);




EDIT: I tracked down the line of React that re-renders the page and consequently resets the scroll position after it already scrolled where I told it to go in componentDidMount(). It's this one.
style[styleName] = styleValue; At the time the page is re-rendered it is setting the width style property of the inputbox component of the react-select box component. The stack trace right before it does this looks like



(anonymous) @ VM38319:1
setValueForStyles @ react-dom.development.js:6426
updateDOMProperties @ react-dom.development.js:7587
updateProperties @ react-dom.development.js:7953
commitUpdate @ react-dom.development.js:8797
commitWork @ react-dom.development.js:17915
commitAllHostEffects @ react-dom.development.js:18634
callCallback @ react-dom.development.js:149
invokeGuardedCallbackDev @ react-dom.development.js:199
invokeGuardedCallback @ react-dom.development.js:256
commitRoot @ react-dom.development.js:18867
(anonymous) @ react-dom.development.js:20372
unstable_runWithPriority @ scheduler.development.js:255
completeRoot @ react-dom.development.js:20371
performWorkOnRoot @ react-dom.development.js:20300
performWork @ react-dom.development.js:20208
performSyncWork @ react-dom.development.js:20182
requestWork @ react-dom.development.js:20051
scheduleWork @ react-dom.development.js:19865
scheduleRootUpdate @ react-dom.development.js:20526
updateContainerAtExpirationTime @ react-dom.development.js:20554
updateContainer @ react-dom.development.js:20611
ReactRoot.render @ react-dom.development.js:20907
(anonymous) @ react-dom.development.js:21044
unbatchedUpdates @ react-dom.development.js:20413
legacyRenderSubtreeIntoContainer @ react-dom.development.js:21040
render @ react-dom.development.js:21109
(anonymous) @ questionsPageIndex.jsx:10
./src/client/questionsPageIndex.jsx @ index.html:673
__webpack_require__ @ index.html:32
(anonymous) @ index.html:96
(anonymous) @ index.html:99


I don't know where to move my instruction to scroll the page. It has to happen after these styles are set which is happening after componentDidMount().



EDIT: I need to better clarify exactly what I need this to do. Apologies for not doing that before.



Must haves



This has to work on all common desktop and mobile devices.



When the page loads there could be three situations depending on what query is provided in the url after the #:



  • 1) no query was provided - nothing happens

  • 2) a valid query was provided - the page scrolls instantly to the desired anchor and the page's title changes to the label of the option

  • 3) an invalid query was provided - the query is entered into the search box, the search box is focused and the menu opens with options limited by the provided query as if they had been typed in. The cursor is located in the search box at the end of the query so the user can modify the query.

A valid query is one that matches the value of one of the options. An invalid query is one that doesn't.



The browser back and forward buttons should move the scroll position accordingly.



Any time an option is chosen from the Search box the page should scroll instantly to that anchor, the query should clear returning to the placeholder "Search...", the url should update, and the document's title should change to the option's label.



Optional but would be great



After making a selection the menu closes and the query goes back to "Search...", and either



  • the Search box retains the focus so the user can begin typing another query. The next time it is clicked, the menu opens, and the Searchbox query from before the selection, the menu's filter and the menu scroll position are restored (most preferred), or

  • the Search box loses focus. The next time it is focused, the menu opens, and the Search box query from before the selection, the menu's filter and the menu scroll position are restored (preferred), or

  • the Search box retains the focus so the user can begin typing another query. The prior query and menu scroll position are lost.









share|improve this question
















I want to pass a value as the hash in the url (myapp.com#somevalue) and have the page scroll to that item when the page loads - exactly the behavior of using a hash fragment since the beginning of the internet. I tried using scrollIntoView but that fails on iOS. Then I tried just unsetting/setting window.location.hash but there seems to be a race condition. It only works when the delay is more than 600ms.



I would like a more solid solution and don't want to introduce an unnecessary delay. When the delay is too short, it appears to scroll to the desired item but then scrolls to the top of the page. You won't see the effect on this demo but it happens in my actual app https://codesandbox.io/s/pjok544nrx line 75



 componentDidMount() 
let self = this;

let updateSearchControl = hash =>
let selectedOption = self.state.searchOptions.filter(
option => option.value === hash
)[0];
if (selectedOption)
// this doesn't work with Safari on iOS
// document.getElementById(hash).scrollIntoView(true);

// this works if delay is 900 but not 500 ms
setTimeout(() =>
// unset and set the hash to trigger scrolling to target
window.location.hash = null;
window.location.hash = hash;
// scroll back by the height of the Search box
window.scrollBy(
0,
-document.getElementsByClassName("heading")[0].clientHeight
);
, 900);
else if (hash)
this.searchRef.current.select.focus();

;

// Get the hash
// I want this to work as a Google Apps Script too which runs in
// an iframe and has a special way to get the hash
if (!!window["google"])
let updateHash = location =>
updateSearchControl(location.hash);
;
eval("google.script.url.getLocation(updateHash)");
else
let hash = window.location.hash.slice(1);
updateSearchControl(hash);




EDIT: I tracked down the line of React that re-renders the page and consequently resets the scroll position after it already scrolled where I told it to go in componentDidMount(). It's this one.
style[styleName] = styleValue; At the time the page is re-rendered it is setting the width style property of the inputbox component of the react-select box component. The stack trace right before it does this looks like



(anonymous) @ VM38319:1
setValueForStyles @ react-dom.development.js:6426
updateDOMProperties @ react-dom.development.js:7587
updateProperties @ react-dom.development.js:7953
commitUpdate @ react-dom.development.js:8797
commitWork @ react-dom.development.js:17915
commitAllHostEffects @ react-dom.development.js:18634
callCallback @ react-dom.development.js:149
invokeGuardedCallbackDev @ react-dom.development.js:199
invokeGuardedCallback @ react-dom.development.js:256
commitRoot @ react-dom.development.js:18867
(anonymous) @ react-dom.development.js:20372
unstable_runWithPriority @ scheduler.development.js:255
completeRoot @ react-dom.development.js:20371
performWorkOnRoot @ react-dom.development.js:20300
performWork @ react-dom.development.js:20208
performSyncWork @ react-dom.development.js:20182
requestWork @ react-dom.development.js:20051
scheduleWork @ react-dom.development.js:19865
scheduleRootUpdate @ react-dom.development.js:20526
updateContainerAtExpirationTime @ react-dom.development.js:20554
updateContainer @ react-dom.development.js:20611
ReactRoot.render @ react-dom.development.js:20907
(anonymous) @ react-dom.development.js:21044
unbatchedUpdates @ react-dom.development.js:20413
legacyRenderSubtreeIntoContainer @ react-dom.development.js:21040
render @ react-dom.development.js:21109
(anonymous) @ questionsPageIndex.jsx:10
./src/client/questionsPageIndex.jsx @ index.html:673
__webpack_require__ @ index.html:32
(anonymous) @ index.html:96
(anonymous) @ index.html:99


I don't know where to move my instruction to scroll the page. It has to happen after these styles are set which is happening after componentDidMount().



EDIT: I need to better clarify exactly what I need this to do. Apologies for not doing that before.



Must haves



This has to work on all common desktop and mobile devices.



When the page loads there could be three situations depending on what query is provided in the url after the #:



  • 1) no query was provided - nothing happens

  • 2) a valid query was provided - the page scrolls instantly to the desired anchor and the page's title changes to the label of the option

  • 3) an invalid query was provided - the query is entered into the search box, the search box is focused and the menu opens with options limited by the provided query as if they had been typed in. The cursor is located in the search box at the end of the query so the user can modify the query.

A valid query is one that matches the value of one of the options. An invalid query is one that doesn't.



The browser back and forward buttons should move the scroll position accordingly.



Any time an option is chosen from the Search box the page should scroll instantly to that anchor, the query should clear returning to the placeholder "Search...", the url should update, and the document's title should change to the option's label.



Optional but would be great



After making a selection the menu closes and the query goes back to "Search...", and either



  • the Search box retains the focus so the user can begin typing another query. The next time it is clicked, the menu opens, and the Searchbox query from before the selection, the menu's filter and the menu scroll position are restored (most preferred), or

  • the Search box loses focus. The next time it is focused, the menu opens, and the Search box query from before the selection, the menu's filter and the menu scroll position are restored (preferred), or

  • the Search box retains the focus so the user can begin typing another query. The prior query and menu scroll position are lost.






reactjs react-select






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 28 at 14:08







Dan Cancro

















asked Mar 22 at 15:41









Dan CancroDan Cancro

1,14411234




1,14411234







  • 1





    possible solution - stackoverflow.com/questions/3163615/…

    – fard
    Mar 22 at 15:47











  • maybe useEffect is worth to give it a try. as I understand useEffect will run after rendering submitted to the screen and at that time the element is ready to scroll to

    – duc mai
    Mar 29 at 18:29












  • 1





    possible solution - stackoverflow.com/questions/3163615/…

    – fard
    Mar 22 at 15:47











  • maybe useEffect is worth to give it a try. as I understand useEffect will run after rendering submitted to the screen and at that time the element is ready to scroll to

    – duc mai
    Mar 29 at 18:29







1




1





possible solution - stackoverflow.com/questions/3163615/…

– fard
Mar 22 at 15:47





possible solution - stackoverflow.com/questions/3163615/…

– fard
Mar 22 at 15:47













maybe useEffect is worth to give it a try. as I understand useEffect will run after rendering submitted to the screen and at that time the element is ready to scroll to

– duc mai
Mar 29 at 18:29





maybe useEffect is worth to give it a try. as I understand useEffect will run after rendering submitted to the screen and at that time the element is ready to scroll to

– duc mai
Mar 29 at 18:29












4 Answers
4






active

oldest

votes


















1














Probably easier to do this with the react-scrollable-anchor library:



import React from "react";
import ReactDOM from "react-dom";
import ScrollableAnchor from "react-scrollable-anchor";

class App extends React.Component
render()
return (
<React.Fragment>
<div style= marginBottom: 7000 >nothing to see here</div>
<div style= marginBottom: 7000 >never mind me</div>
<ScrollableAnchor id="doge">
<div>bork</div>
</ScrollableAnchor>
</React.Fragment>
);



const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);


You can see it working by going here: https://zwoj0xw503.codesandbox.io/#doge






share|improve this answer























  • Internally, ScrollableAnchors effects the scrolling by setting window.location.hash, so it has the same answer to the What question and doesn't answer the When question. If this is indeed a matter for TC39 as it seems, and given that I didn't immediately receive any instant answers that capturing the "ready to be scrolled event" is impossible, I must be violating a basic principal of web design on my first project, but that is really hard to accept. This seems like an eminently reasonable requirement. github.com/gabergg/react-scrollable-anchor/blob/master/src/…

    – Dan Cancro
    Mar 28 at 14:48


















1














I put this right after the imports in my component's file:



let initialValidSlug = '';

window.addEventListener('load', () =>
window.location.hash = '';
window.location.hash = (initialValidSlug ? initialValidSlug : '');
window.scrollBy(0, -document.getElementsByClassName("heading")[0].clientHeight);
console.log('window.addEventListener')
);


and have this for my componentDidMount():



 componentDidMount() 
const pathname, isValid = this.state;
if(!isValid && pathname) // if there's a pathname but it's invalid,
this.searchRef.current.select.focus(); // focus on the search bar

initialValidSlug = pathname; // sets the value to be used in the $.ready() above






share|improve this answer
































    0





    +100









    You can simplify your code by using react-router-dom's HashRouter with React's ref.current.scrollIntoView() or window.scrollTo(ref.currrent.offsetTop).



    Currently tested and working on Chrome (desktop/android), Firefox(desktop), Silk Browser(android), Saumsung Internet(android), and Safari(iOS -- with one caveat in that it instantly jumps to the selection). While I was able to test and confirm it's working within the sandbox environment's iframe, you'll have to adapt/test it within a standalone iframe.



    I'd also like to point out that your approach is very jQuery like and that you should avoid directly attempting to utilize or manipulate the DOM and/or the window. In addition, you seem to use a lot of let variables throughout your code, but they remain unchanged. Instead, they should be a const variable as React evaluates variables each time it re-renders, so unless you plan on changing that variable during the re-render process, there's no need to use let.



    Working example: https://v6y5211n4l.codesandbox.io



    Edit ScrollIntoView on Selection




    components/ScrollBar



    import React, Component from "react";
    import PropTypes from "prop-types";
    import Helmet from "react-helmet";
    import Select from "react-select";
    import withRouter from "react-router-dom";
    import "./styles.css";

    const scrollOpts =
    behavior: "smooth",
    block: "start"
    ;

    class ScrollBar extends Component
    constructor(props)
    super(props);

    const titleRefs = props.searchOptions.map(
    ( label ) => (this[label] = React.createRef())
    ); // map over options and use "label" as a ref name; ex: this.orange
    this.topWindow = React.createRef();
    this.searchRef = React.createRef();
    const pathname = props.history.location.pathname.replace(///g, ""); // set current pathname without the "/"

    this.state =
    titleRefs,
    menuIsOpen: false,
    isValid: props.searchOptions.some(( label ) => label === pathname), // check if the current pathname matches any of the labels
    pathname
    ;


    componentDidMount()
    const pathname, isValid = this.state;
    if (isValid) this.scrollToElement(); // if theres a pathname and it matches a label, scroll to it
    if (!isValid && pathname) this.searchRef.current.select.focus(); // if there's a pathname but it's invalid, focus on the search bar


    // allows us to update state based upon prop updates (in this case
    // we're looking for changes in the history.location.pathname)
    static getDerivedStateFromProps(props, state)
    const nextPath = props.history.location.pathname.replace(///g, "");
    const isValid = props.searchOptions.some(( label ) => label === nextPath);
    return state.pathname !== nextPath ? pathname: nextPath, isValid : null; // if the path has changed, update the pathname and whether or not it is valid


    // allows us to compare new state to old state (in this case
    // we're looking for changes in the pathname)
    componentDidUpdate(prevProps, prevState)
    if (this.state.pathname !== prevState.pathname)
    this.scrollToElement();



    scrollToElement = () =>
    const isValid, pathname = this.state;
    const elem = isValid ? pathname : "topWindow";
    setTimeout(() =>
    window.scrollTo(
    behavior: "smooth",
    top: this[elem].current.offsetTop - 45
    );
    , 100);
    ;

    onInputChange = (options, action ) =>
    if (action === "menu-close")
    this.setState( menuIsOpen: false , () =>
    this.searchRef.current.select.blur()
    );
    else
    this.setState( menuIsOpen: true );

    ;

    onChange = ( value ) =>
    const history = this.props;
    if (history.location.pathname.replace(///g, "") !== value) // if the select value is different than the previous selected value, update the url -- required, otherwise, react-router will complain about pushing the same pathname/value that is current in the url
    history.push(value);

    this.searchRef.current.select.blur();
    ;

    onFocus = () => this.setState( menuIsOpen: true );

    render()
    const pathname, menuIsOpen, titleRefs = this.state;
    const searchOptions, styles = this.props;

    return (
    <div className="container">
    <Helmet title= "Select an option" />
    <div className="heading">
    <Select
    placeholder="Search..."
    isClearable=true
    isSearchable=true
    options=searchOptions
    defaultInputValue=pathname
    onFocus=this.onFocus
    onInputChange=this.onInputChange
    onChange=this.onChange
    menuIsOpen=menuIsOpen
    ref=this.searchRef
    value=null
    styles=
    />
    </div>
    <div className="fruits-list">
    <div ref=this.topWindow />
    searchOptions.map(( label, value , key) => (
    <div key=value id=value>
    <p ref=titleRefs[key]>label</p>
    [1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14].map(num => (
    <p key=num>num</p>
    ))
    </div>
    ))
    </div>
    </div>
    );



    ScrollBar.propTypes =
    searchOptions: PropTypes.arrayOf(
    PropTypes.shape(
    label: PropTypes.string.isRequired,
    value: PropTypes.string.isRequired
    ).isRequired
    ).isRequired,
    styles: PropTypes.objectOf(PropTypes.func)
    ;

    export default withRouter(ScrollBar);


    index.js



    import React from "react";
    import render from "react-dom";
    import HashRouter from "react-router-dom";
    import Helmet from "react-helmet";
    import ScrollBar from "../src/components/ScrollBar";

    const config =
    htmlAttributes: lang: "en" ,
    title: "My App",
    titleTemplate: "Scroll Search - %s",
    meta: [

    name: "description",
    content: "The best app in the world."

    ]
    ;

    const searchOptions = [

    label: "apple",
    value: "apple"
    ,

    label: "orange",
    value: "orange"
    ,

    label: "banana",
    value: "banana"
    ,

    label: "strawberry",
    value: "strawberry"

    ];

    const styles =
    menu: base => ( ...base, width: "100%", height: "75vh" ),
    menuList: base => ( ...base, minHeight: "75vh" ),
    option: base => ( ...base, color: "blue" )
    ;

    const App = () => (
    <HashRouter>
    <Helmet ...config />
    <ScrollBar searchOptions=searchOptions styles=styles />
    </HashRouter>
    );

    render(<App />, document.getElementById("root"));





    share|improve this answer

























    • That's great, thanks. It handles well the case when a valid value is provided but I also want to handle when an invalid one is. I clarified the details above and started work on a modification of your solution here codesandbox.io/s/xl46pnmr8p

      – Dan Cancro
      Mar 26 at 17:18











    • Updated answer above. Also, the setTimeout is required for mobile browsers. Otherwise, it won't scroll.

      – Matt Carlotta
      Mar 26 at 18:23











    • Just finished. It works on my computer but it doesn't work in Safari on my iPhone. It will scroll to the correct spot on load but the Search box disappears. If you manually swipe all the way back up, and then swipe one more time, the box comes back. The Search box stays put if you manually scroll but scrollIntoView() does not work on this device. Please try this on mobile: v6y5211n4l.codesandbox.io/#/orange

      – Dan Cancro
      Mar 27 at 1:38











    • Updated answer. That's a problem with mobile not liking overflow: hidden; on the body and position: absolute; on the Select component. Instead, set .heading as position: fixed; width: 100%; and remove the overflow: hidden;. As such, you'll have to use an window.scrollTo() with an offsetTop calculation, which will scroll to the correct location (since a fixed position floats above, you'll have to offset it, otherwise it'll land directly on top of the ref). In addition, another drawback is that when using the back button it immediately jumps to the last selected location.

      – Matt Carlotta
      Mar 27 at 3:19












    • No matter which direction you take, ref.scrollIntoView() or window.scrollTo() you're going to run into browser limitations.

      – Matt Carlotta
      Mar 27 at 3:22


















    -1














    You can use https://www.npmjs.com/package/element.scrollintoviewifneeded-polyfill.



    As soon as possibile in your application import the library



    import 'element.scrollintoviewifneeded-polyfill';


    Than you can use the method scrollIntoViewIfNeeded(); on all the dom nodes.
    The library will polyfill the method so you could use this on all browsers.



    I recommend you to use this with a react ref so you don't have to call getElementById or other document method in order to retrieve the dom node.



    const ref = React.createRef();
    <div id="somevalue" ref=ref />


    Than in your componentDidMount you can use the same method you describe for retrieving the id of the div you want to scroll in, get the associated ref and call



     ref.current.scrollIntoViewIfNeeded();


    Where the ref is the right div reference, you can obviously store all the ref in a map and than retrieve in your components methods.






    share|improve this answer

























    • Thanks. Unfortunately it is still doing it. It jumps to the right place, then jumps back to the top. github.com/dancancro/questions/blob/nodiv/src/client/components/…

      – Dan Cancro
      Mar 22 at 17:44











    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55303221%2fhow-to-scroll-a-react-page-when-it-loads%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    Probably easier to do this with the react-scrollable-anchor library:



    import React from "react";
    import ReactDOM from "react-dom";
    import ScrollableAnchor from "react-scrollable-anchor";

    class App extends React.Component
    render()
    return (
    <React.Fragment>
    <div style= marginBottom: 7000 >nothing to see here</div>
    <div style= marginBottom: 7000 >never mind me</div>
    <ScrollableAnchor id="doge">
    <div>bork</div>
    </ScrollableAnchor>
    </React.Fragment>
    );



    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);


    You can see it working by going here: https://zwoj0xw503.codesandbox.io/#doge






    share|improve this answer























    • Internally, ScrollableAnchors effects the scrolling by setting window.location.hash, so it has the same answer to the What question and doesn't answer the When question. If this is indeed a matter for TC39 as it seems, and given that I didn't immediately receive any instant answers that capturing the "ready to be scrolled event" is impossible, I must be violating a basic principal of web design on my first project, but that is really hard to accept. This seems like an eminently reasonable requirement. github.com/gabergg/react-scrollable-anchor/blob/master/src/…

      – Dan Cancro
      Mar 28 at 14:48















    1














    Probably easier to do this with the react-scrollable-anchor library:



    import React from "react";
    import ReactDOM from "react-dom";
    import ScrollableAnchor from "react-scrollable-anchor";

    class App extends React.Component
    render()
    return (
    <React.Fragment>
    <div style= marginBottom: 7000 >nothing to see here</div>
    <div style= marginBottom: 7000 >never mind me</div>
    <ScrollableAnchor id="doge">
    <div>bork</div>
    </ScrollableAnchor>
    </React.Fragment>
    );



    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);


    You can see it working by going here: https://zwoj0xw503.codesandbox.io/#doge






    share|improve this answer























    • Internally, ScrollableAnchors effects the scrolling by setting window.location.hash, so it has the same answer to the What question and doesn't answer the When question. If this is indeed a matter for TC39 as it seems, and given that I didn't immediately receive any instant answers that capturing the "ready to be scrolled event" is impossible, I must be violating a basic principal of web design on my first project, but that is really hard to accept. This seems like an eminently reasonable requirement. github.com/gabergg/react-scrollable-anchor/blob/master/src/…

      – Dan Cancro
      Mar 28 at 14:48













    1












    1








    1







    Probably easier to do this with the react-scrollable-anchor library:



    import React from "react";
    import ReactDOM from "react-dom";
    import ScrollableAnchor from "react-scrollable-anchor";

    class App extends React.Component
    render()
    return (
    <React.Fragment>
    <div style= marginBottom: 7000 >nothing to see here</div>
    <div style= marginBottom: 7000 >never mind me</div>
    <ScrollableAnchor id="doge">
    <div>bork</div>
    </ScrollableAnchor>
    </React.Fragment>
    );



    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);


    You can see it working by going here: https://zwoj0xw503.codesandbox.io/#doge






    share|improve this answer













    Probably easier to do this with the react-scrollable-anchor library:



    import React from "react";
    import ReactDOM from "react-dom";
    import ScrollableAnchor from "react-scrollable-anchor";

    class App extends React.Component
    render()
    return (
    <React.Fragment>
    <div style= marginBottom: 7000 >nothing to see here</div>
    <div style= marginBottom: 7000 >never mind me</div>
    <ScrollableAnchor id="doge">
    <div>bork</div>
    </ScrollableAnchor>
    </React.Fragment>
    );



    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);


    You can see it working by going here: https://zwoj0xw503.codesandbox.io/#doge







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Mar 25 at 22:32









    codecubed.iocodecubed.io

    5,0512931




    5,0512931












    • Internally, ScrollableAnchors effects the scrolling by setting window.location.hash, so it has the same answer to the What question and doesn't answer the When question. If this is indeed a matter for TC39 as it seems, and given that I didn't immediately receive any instant answers that capturing the "ready to be scrolled event" is impossible, I must be violating a basic principal of web design on my first project, but that is really hard to accept. This seems like an eminently reasonable requirement. github.com/gabergg/react-scrollable-anchor/blob/master/src/…

      – Dan Cancro
      Mar 28 at 14:48

















    • Internally, ScrollableAnchors effects the scrolling by setting window.location.hash, so it has the same answer to the What question and doesn't answer the When question. If this is indeed a matter for TC39 as it seems, and given that I didn't immediately receive any instant answers that capturing the "ready to be scrolled event" is impossible, I must be violating a basic principal of web design on my first project, but that is really hard to accept. This seems like an eminently reasonable requirement. github.com/gabergg/react-scrollable-anchor/blob/master/src/…

      – Dan Cancro
      Mar 28 at 14:48
















    Internally, ScrollableAnchors effects the scrolling by setting window.location.hash, so it has the same answer to the What question and doesn't answer the When question. If this is indeed a matter for TC39 as it seems, and given that I didn't immediately receive any instant answers that capturing the "ready to be scrolled event" is impossible, I must be violating a basic principal of web design on my first project, but that is really hard to accept. This seems like an eminently reasonable requirement. github.com/gabergg/react-scrollable-anchor/blob/master/src/…

    – Dan Cancro
    Mar 28 at 14:48





    Internally, ScrollableAnchors effects the scrolling by setting window.location.hash, so it has the same answer to the What question and doesn't answer the When question. If this is indeed a matter for TC39 as it seems, and given that I didn't immediately receive any instant answers that capturing the "ready to be scrolled event" is impossible, I must be violating a basic principal of web design on my first project, but that is really hard to accept. This seems like an eminently reasonable requirement. github.com/gabergg/react-scrollable-anchor/blob/master/src/…

    – Dan Cancro
    Mar 28 at 14:48













    1














    I put this right after the imports in my component's file:



    let initialValidSlug = '';

    window.addEventListener('load', () =>
    window.location.hash = '';
    window.location.hash = (initialValidSlug ? initialValidSlug : '');
    window.scrollBy(0, -document.getElementsByClassName("heading")[0].clientHeight);
    console.log('window.addEventListener')
    );


    and have this for my componentDidMount():



     componentDidMount() 
    const pathname, isValid = this.state;
    if(!isValid && pathname) // if there's a pathname but it's invalid,
    this.searchRef.current.select.focus(); // focus on the search bar

    initialValidSlug = pathname; // sets the value to be used in the $.ready() above






    share|improve this answer





























      1














      I put this right after the imports in my component's file:



      let initialValidSlug = '';

      window.addEventListener('load', () =>
      window.location.hash = '';
      window.location.hash = (initialValidSlug ? initialValidSlug : '');
      window.scrollBy(0, -document.getElementsByClassName("heading")[0].clientHeight);
      console.log('window.addEventListener')
      );


      and have this for my componentDidMount():



       componentDidMount() 
      const pathname, isValid = this.state;
      if(!isValid && pathname) // if there's a pathname but it's invalid,
      this.searchRef.current.select.focus(); // focus on the search bar

      initialValidSlug = pathname; // sets the value to be used in the $.ready() above






      share|improve this answer



























        1












        1








        1







        I put this right after the imports in my component's file:



        let initialValidSlug = '';

        window.addEventListener('load', () =>
        window.location.hash = '';
        window.location.hash = (initialValidSlug ? initialValidSlug : '');
        window.scrollBy(0, -document.getElementsByClassName("heading")[0].clientHeight);
        console.log('window.addEventListener')
        );


        and have this for my componentDidMount():



         componentDidMount() 
        const pathname, isValid = this.state;
        if(!isValid && pathname) // if there's a pathname but it's invalid,
        this.searchRef.current.select.focus(); // focus on the search bar

        initialValidSlug = pathname; // sets the value to be used in the $.ready() above






        share|improve this answer















        I put this right after the imports in my component's file:



        let initialValidSlug = '';

        window.addEventListener('load', () =>
        window.location.hash = '';
        window.location.hash = (initialValidSlug ? initialValidSlug : '');
        window.scrollBy(0, -document.getElementsByClassName("heading")[0].clientHeight);
        console.log('window.addEventListener')
        );


        and have this for my componentDidMount():



         componentDidMount() 
        const pathname, isValid = this.state;
        if(!isValid && pathname) // if there's a pathname but it's invalid,
        this.searchRef.current.select.focus(); // focus on the search bar

        initialValidSlug = pathname; // sets the value to be used in the $.ready() above







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 29 at 21:25

























        answered Mar 29 at 1:48









        Dan CancroDan Cancro

        1,14411234




        1,14411234





















            0





            +100









            You can simplify your code by using react-router-dom's HashRouter with React's ref.current.scrollIntoView() or window.scrollTo(ref.currrent.offsetTop).



            Currently tested and working on Chrome (desktop/android), Firefox(desktop), Silk Browser(android), Saumsung Internet(android), and Safari(iOS -- with one caveat in that it instantly jumps to the selection). While I was able to test and confirm it's working within the sandbox environment's iframe, you'll have to adapt/test it within a standalone iframe.



            I'd also like to point out that your approach is very jQuery like and that you should avoid directly attempting to utilize or manipulate the DOM and/or the window. In addition, you seem to use a lot of let variables throughout your code, but they remain unchanged. Instead, they should be a const variable as React evaluates variables each time it re-renders, so unless you plan on changing that variable during the re-render process, there's no need to use let.



            Working example: https://v6y5211n4l.codesandbox.io



            Edit ScrollIntoView on Selection




            components/ScrollBar



            import React, Component from "react";
            import PropTypes from "prop-types";
            import Helmet from "react-helmet";
            import Select from "react-select";
            import withRouter from "react-router-dom";
            import "./styles.css";

            const scrollOpts =
            behavior: "smooth",
            block: "start"
            ;

            class ScrollBar extends Component
            constructor(props)
            super(props);

            const titleRefs = props.searchOptions.map(
            ( label ) => (this[label] = React.createRef())
            ); // map over options and use "label" as a ref name; ex: this.orange
            this.topWindow = React.createRef();
            this.searchRef = React.createRef();
            const pathname = props.history.location.pathname.replace(///g, ""); // set current pathname without the "/"

            this.state =
            titleRefs,
            menuIsOpen: false,
            isValid: props.searchOptions.some(( label ) => label === pathname), // check if the current pathname matches any of the labels
            pathname
            ;


            componentDidMount()
            const pathname, isValid = this.state;
            if (isValid) this.scrollToElement(); // if theres a pathname and it matches a label, scroll to it
            if (!isValid && pathname) this.searchRef.current.select.focus(); // if there's a pathname but it's invalid, focus on the search bar


            // allows us to update state based upon prop updates (in this case
            // we're looking for changes in the history.location.pathname)
            static getDerivedStateFromProps(props, state)
            const nextPath = props.history.location.pathname.replace(///g, "");
            const isValid = props.searchOptions.some(( label ) => label === nextPath);
            return state.pathname !== nextPath ? pathname: nextPath, isValid : null; // if the path has changed, update the pathname and whether or not it is valid


            // allows us to compare new state to old state (in this case
            // we're looking for changes in the pathname)
            componentDidUpdate(prevProps, prevState)
            if (this.state.pathname !== prevState.pathname)
            this.scrollToElement();



            scrollToElement = () =>
            const isValid, pathname = this.state;
            const elem = isValid ? pathname : "topWindow";
            setTimeout(() =>
            window.scrollTo(
            behavior: "smooth",
            top: this[elem].current.offsetTop - 45
            );
            , 100);
            ;

            onInputChange = (options, action ) =>
            if (action === "menu-close")
            this.setState( menuIsOpen: false , () =>
            this.searchRef.current.select.blur()
            );
            else
            this.setState( menuIsOpen: true );

            ;

            onChange = ( value ) =>
            const history = this.props;
            if (history.location.pathname.replace(///g, "") !== value) // if the select value is different than the previous selected value, update the url -- required, otherwise, react-router will complain about pushing the same pathname/value that is current in the url
            history.push(value);

            this.searchRef.current.select.blur();
            ;

            onFocus = () => this.setState( menuIsOpen: true );

            render()
            const pathname, menuIsOpen, titleRefs = this.state;
            const searchOptions, styles = this.props;

            return (
            <div className="container">
            <Helmet title= "Select an option" />
            <div className="heading">
            <Select
            placeholder="Search..."
            isClearable=true
            isSearchable=true
            options=searchOptions
            defaultInputValue=pathname
            onFocus=this.onFocus
            onInputChange=this.onInputChange
            onChange=this.onChange
            menuIsOpen=menuIsOpen
            ref=this.searchRef
            value=null
            styles=
            />
            </div>
            <div className="fruits-list">
            <div ref=this.topWindow />
            searchOptions.map(( label, value , key) => (
            <div key=value id=value>
            <p ref=titleRefs[key]>label</p>
            [1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14].map(num => (
            <p key=num>num</p>
            ))
            </div>
            ))
            </div>
            </div>
            );



            ScrollBar.propTypes =
            searchOptions: PropTypes.arrayOf(
            PropTypes.shape(
            label: PropTypes.string.isRequired,
            value: PropTypes.string.isRequired
            ).isRequired
            ).isRequired,
            styles: PropTypes.objectOf(PropTypes.func)
            ;

            export default withRouter(ScrollBar);


            index.js



            import React from "react";
            import render from "react-dom";
            import HashRouter from "react-router-dom";
            import Helmet from "react-helmet";
            import ScrollBar from "../src/components/ScrollBar";

            const config =
            htmlAttributes: lang: "en" ,
            title: "My App",
            titleTemplate: "Scroll Search - %s",
            meta: [

            name: "description",
            content: "The best app in the world."

            ]
            ;

            const searchOptions = [

            label: "apple",
            value: "apple"
            ,

            label: "orange",
            value: "orange"
            ,

            label: "banana",
            value: "banana"
            ,

            label: "strawberry",
            value: "strawberry"

            ];

            const styles =
            menu: base => ( ...base, width: "100%", height: "75vh" ),
            menuList: base => ( ...base, minHeight: "75vh" ),
            option: base => ( ...base, color: "blue" )
            ;

            const App = () => (
            <HashRouter>
            <Helmet ...config />
            <ScrollBar searchOptions=searchOptions styles=styles />
            </HashRouter>
            );

            render(<App />, document.getElementById("root"));





            share|improve this answer

























            • That's great, thanks. It handles well the case when a valid value is provided but I also want to handle when an invalid one is. I clarified the details above and started work on a modification of your solution here codesandbox.io/s/xl46pnmr8p

              – Dan Cancro
              Mar 26 at 17:18











            • Updated answer above. Also, the setTimeout is required for mobile browsers. Otherwise, it won't scroll.

              – Matt Carlotta
              Mar 26 at 18:23











            • Just finished. It works on my computer but it doesn't work in Safari on my iPhone. It will scroll to the correct spot on load but the Search box disappears. If you manually swipe all the way back up, and then swipe one more time, the box comes back. The Search box stays put if you manually scroll but scrollIntoView() does not work on this device. Please try this on mobile: v6y5211n4l.codesandbox.io/#/orange

              – Dan Cancro
              Mar 27 at 1:38











            • Updated answer. That's a problem with mobile not liking overflow: hidden; on the body and position: absolute; on the Select component. Instead, set .heading as position: fixed; width: 100%; and remove the overflow: hidden;. As such, you'll have to use an window.scrollTo() with an offsetTop calculation, which will scroll to the correct location (since a fixed position floats above, you'll have to offset it, otherwise it'll land directly on top of the ref). In addition, another drawback is that when using the back button it immediately jumps to the last selected location.

              – Matt Carlotta
              Mar 27 at 3:19












            • No matter which direction you take, ref.scrollIntoView() or window.scrollTo() you're going to run into browser limitations.

              – Matt Carlotta
              Mar 27 at 3:22















            0





            +100









            You can simplify your code by using react-router-dom's HashRouter with React's ref.current.scrollIntoView() or window.scrollTo(ref.currrent.offsetTop).



            Currently tested and working on Chrome (desktop/android), Firefox(desktop), Silk Browser(android), Saumsung Internet(android), and Safari(iOS -- with one caveat in that it instantly jumps to the selection). While I was able to test and confirm it's working within the sandbox environment's iframe, you'll have to adapt/test it within a standalone iframe.



            I'd also like to point out that your approach is very jQuery like and that you should avoid directly attempting to utilize or manipulate the DOM and/or the window. In addition, you seem to use a lot of let variables throughout your code, but they remain unchanged. Instead, they should be a const variable as React evaluates variables each time it re-renders, so unless you plan on changing that variable during the re-render process, there's no need to use let.



            Working example: https://v6y5211n4l.codesandbox.io



            Edit ScrollIntoView on Selection




            components/ScrollBar



            import React, Component from "react";
            import PropTypes from "prop-types";
            import Helmet from "react-helmet";
            import Select from "react-select";
            import withRouter from "react-router-dom";
            import "./styles.css";

            const scrollOpts =
            behavior: "smooth",
            block: "start"
            ;

            class ScrollBar extends Component
            constructor(props)
            super(props);

            const titleRefs = props.searchOptions.map(
            ( label ) => (this[label] = React.createRef())
            ); // map over options and use "label" as a ref name; ex: this.orange
            this.topWindow = React.createRef();
            this.searchRef = React.createRef();
            const pathname = props.history.location.pathname.replace(///g, ""); // set current pathname without the "/"

            this.state =
            titleRefs,
            menuIsOpen: false,
            isValid: props.searchOptions.some(( label ) => label === pathname), // check if the current pathname matches any of the labels
            pathname
            ;


            componentDidMount()
            const pathname, isValid = this.state;
            if (isValid) this.scrollToElement(); // if theres a pathname and it matches a label, scroll to it
            if (!isValid && pathname) this.searchRef.current.select.focus(); // if there's a pathname but it's invalid, focus on the search bar


            // allows us to update state based upon prop updates (in this case
            // we're looking for changes in the history.location.pathname)
            static getDerivedStateFromProps(props, state)
            const nextPath = props.history.location.pathname.replace(///g, "");
            const isValid = props.searchOptions.some(( label ) => label === nextPath);
            return state.pathname !== nextPath ? pathname: nextPath, isValid : null; // if the path has changed, update the pathname and whether or not it is valid


            // allows us to compare new state to old state (in this case
            // we're looking for changes in the pathname)
            componentDidUpdate(prevProps, prevState)
            if (this.state.pathname !== prevState.pathname)
            this.scrollToElement();



            scrollToElement = () =>
            const isValid, pathname = this.state;
            const elem = isValid ? pathname : "topWindow";
            setTimeout(() =>
            window.scrollTo(
            behavior: "smooth",
            top: this[elem].current.offsetTop - 45
            );
            , 100);
            ;

            onInputChange = (options, action ) =>
            if (action === "menu-close")
            this.setState( menuIsOpen: false , () =>
            this.searchRef.current.select.blur()
            );
            else
            this.setState( menuIsOpen: true );

            ;

            onChange = ( value ) =>
            const history = this.props;
            if (history.location.pathname.replace(///g, "") !== value) // if the select value is different than the previous selected value, update the url -- required, otherwise, react-router will complain about pushing the same pathname/value that is current in the url
            history.push(value);

            this.searchRef.current.select.blur();
            ;

            onFocus = () => this.setState( menuIsOpen: true );

            render()
            const pathname, menuIsOpen, titleRefs = this.state;
            const searchOptions, styles = this.props;

            return (
            <div className="container">
            <Helmet title= "Select an option" />
            <div className="heading">
            <Select
            placeholder="Search..."
            isClearable=true
            isSearchable=true
            options=searchOptions
            defaultInputValue=pathname
            onFocus=this.onFocus
            onInputChange=this.onInputChange
            onChange=this.onChange
            menuIsOpen=menuIsOpen
            ref=this.searchRef
            value=null
            styles=
            />
            </div>
            <div className="fruits-list">
            <div ref=this.topWindow />
            searchOptions.map(( label, value , key) => (
            <div key=value id=value>
            <p ref=titleRefs[key]>label</p>
            [1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14].map(num => (
            <p key=num>num</p>
            ))
            </div>
            ))
            </div>
            </div>
            );



            ScrollBar.propTypes =
            searchOptions: PropTypes.arrayOf(
            PropTypes.shape(
            label: PropTypes.string.isRequired,
            value: PropTypes.string.isRequired
            ).isRequired
            ).isRequired,
            styles: PropTypes.objectOf(PropTypes.func)
            ;

            export default withRouter(ScrollBar);


            index.js



            import React from "react";
            import render from "react-dom";
            import HashRouter from "react-router-dom";
            import Helmet from "react-helmet";
            import ScrollBar from "../src/components/ScrollBar";

            const config =
            htmlAttributes: lang: "en" ,
            title: "My App",
            titleTemplate: "Scroll Search - %s",
            meta: [

            name: "description",
            content: "The best app in the world."

            ]
            ;

            const searchOptions = [

            label: "apple",
            value: "apple"
            ,

            label: "orange",
            value: "orange"
            ,

            label: "banana",
            value: "banana"
            ,

            label: "strawberry",
            value: "strawberry"

            ];

            const styles =
            menu: base => ( ...base, width: "100%", height: "75vh" ),
            menuList: base => ( ...base, minHeight: "75vh" ),
            option: base => ( ...base, color: "blue" )
            ;

            const App = () => (
            <HashRouter>
            <Helmet ...config />
            <ScrollBar searchOptions=searchOptions styles=styles />
            </HashRouter>
            );

            render(<App />, document.getElementById("root"));





            share|improve this answer

























            • That's great, thanks. It handles well the case when a valid value is provided but I also want to handle when an invalid one is. I clarified the details above and started work on a modification of your solution here codesandbox.io/s/xl46pnmr8p

              – Dan Cancro
              Mar 26 at 17:18











            • Updated answer above. Also, the setTimeout is required for mobile browsers. Otherwise, it won't scroll.

              – Matt Carlotta
              Mar 26 at 18:23











            • Just finished. It works on my computer but it doesn't work in Safari on my iPhone. It will scroll to the correct spot on load but the Search box disappears. If you manually swipe all the way back up, and then swipe one more time, the box comes back. The Search box stays put if you manually scroll but scrollIntoView() does not work on this device. Please try this on mobile: v6y5211n4l.codesandbox.io/#/orange

              – Dan Cancro
              Mar 27 at 1:38











            • Updated answer. That's a problem with mobile not liking overflow: hidden; on the body and position: absolute; on the Select component. Instead, set .heading as position: fixed; width: 100%; and remove the overflow: hidden;. As such, you'll have to use an window.scrollTo() with an offsetTop calculation, which will scroll to the correct location (since a fixed position floats above, you'll have to offset it, otherwise it'll land directly on top of the ref). In addition, another drawback is that when using the back button it immediately jumps to the last selected location.

              – Matt Carlotta
              Mar 27 at 3:19












            • No matter which direction you take, ref.scrollIntoView() or window.scrollTo() you're going to run into browser limitations.

              – Matt Carlotta
              Mar 27 at 3:22













            0





            +100







            0





            +100



            0




            +100





            You can simplify your code by using react-router-dom's HashRouter with React's ref.current.scrollIntoView() or window.scrollTo(ref.currrent.offsetTop).



            Currently tested and working on Chrome (desktop/android), Firefox(desktop), Silk Browser(android), Saumsung Internet(android), and Safari(iOS -- with one caveat in that it instantly jumps to the selection). While I was able to test and confirm it's working within the sandbox environment's iframe, you'll have to adapt/test it within a standalone iframe.



            I'd also like to point out that your approach is very jQuery like and that you should avoid directly attempting to utilize or manipulate the DOM and/or the window. In addition, you seem to use a lot of let variables throughout your code, but they remain unchanged. Instead, they should be a const variable as React evaluates variables each time it re-renders, so unless you plan on changing that variable during the re-render process, there's no need to use let.



            Working example: https://v6y5211n4l.codesandbox.io



            Edit ScrollIntoView on Selection




            components/ScrollBar



            import React, Component from "react";
            import PropTypes from "prop-types";
            import Helmet from "react-helmet";
            import Select from "react-select";
            import withRouter from "react-router-dom";
            import "./styles.css";

            const scrollOpts =
            behavior: "smooth",
            block: "start"
            ;

            class ScrollBar extends Component
            constructor(props)
            super(props);

            const titleRefs = props.searchOptions.map(
            ( label ) => (this[label] = React.createRef())
            ); // map over options and use "label" as a ref name; ex: this.orange
            this.topWindow = React.createRef();
            this.searchRef = React.createRef();
            const pathname = props.history.location.pathname.replace(///g, ""); // set current pathname without the "/"

            this.state =
            titleRefs,
            menuIsOpen: false,
            isValid: props.searchOptions.some(( label ) => label === pathname), // check if the current pathname matches any of the labels
            pathname
            ;


            componentDidMount()
            const pathname, isValid = this.state;
            if (isValid) this.scrollToElement(); // if theres a pathname and it matches a label, scroll to it
            if (!isValid && pathname) this.searchRef.current.select.focus(); // if there's a pathname but it's invalid, focus on the search bar


            // allows us to update state based upon prop updates (in this case
            // we're looking for changes in the history.location.pathname)
            static getDerivedStateFromProps(props, state)
            const nextPath = props.history.location.pathname.replace(///g, "");
            const isValid = props.searchOptions.some(( label ) => label === nextPath);
            return state.pathname !== nextPath ? pathname: nextPath, isValid : null; // if the path has changed, update the pathname and whether or not it is valid


            // allows us to compare new state to old state (in this case
            // we're looking for changes in the pathname)
            componentDidUpdate(prevProps, prevState)
            if (this.state.pathname !== prevState.pathname)
            this.scrollToElement();



            scrollToElement = () =>
            const isValid, pathname = this.state;
            const elem = isValid ? pathname : "topWindow";
            setTimeout(() =>
            window.scrollTo(
            behavior: "smooth",
            top: this[elem].current.offsetTop - 45
            );
            , 100);
            ;

            onInputChange = (options, action ) =>
            if (action === "menu-close")
            this.setState( menuIsOpen: false , () =>
            this.searchRef.current.select.blur()
            );
            else
            this.setState( menuIsOpen: true );

            ;

            onChange = ( value ) =>
            const history = this.props;
            if (history.location.pathname.replace(///g, "") !== value) // if the select value is different than the previous selected value, update the url -- required, otherwise, react-router will complain about pushing the same pathname/value that is current in the url
            history.push(value);

            this.searchRef.current.select.blur();
            ;

            onFocus = () => this.setState( menuIsOpen: true );

            render()
            const pathname, menuIsOpen, titleRefs = this.state;
            const searchOptions, styles = this.props;

            return (
            <div className="container">
            <Helmet title= "Select an option" />
            <div className="heading">
            <Select
            placeholder="Search..."
            isClearable=true
            isSearchable=true
            options=searchOptions
            defaultInputValue=pathname
            onFocus=this.onFocus
            onInputChange=this.onInputChange
            onChange=this.onChange
            menuIsOpen=menuIsOpen
            ref=this.searchRef
            value=null
            styles=
            />
            </div>
            <div className="fruits-list">
            <div ref=this.topWindow />
            searchOptions.map(( label, value , key) => (
            <div key=value id=value>
            <p ref=titleRefs[key]>label</p>
            [1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14].map(num => (
            <p key=num>num</p>
            ))
            </div>
            ))
            </div>
            </div>
            );



            ScrollBar.propTypes =
            searchOptions: PropTypes.arrayOf(
            PropTypes.shape(
            label: PropTypes.string.isRequired,
            value: PropTypes.string.isRequired
            ).isRequired
            ).isRequired,
            styles: PropTypes.objectOf(PropTypes.func)
            ;

            export default withRouter(ScrollBar);


            index.js



            import React from "react";
            import render from "react-dom";
            import HashRouter from "react-router-dom";
            import Helmet from "react-helmet";
            import ScrollBar from "../src/components/ScrollBar";

            const config =
            htmlAttributes: lang: "en" ,
            title: "My App",
            titleTemplate: "Scroll Search - %s",
            meta: [

            name: "description",
            content: "The best app in the world."

            ]
            ;

            const searchOptions = [

            label: "apple",
            value: "apple"
            ,

            label: "orange",
            value: "orange"
            ,

            label: "banana",
            value: "banana"
            ,

            label: "strawberry",
            value: "strawberry"

            ];

            const styles =
            menu: base => ( ...base, width: "100%", height: "75vh" ),
            menuList: base => ( ...base, minHeight: "75vh" ),
            option: base => ( ...base, color: "blue" )
            ;

            const App = () => (
            <HashRouter>
            <Helmet ...config />
            <ScrollBar searchOptions=searchOptions styles=styles />
            </HashRouter>
            );

            render(<App />, document.getElementById("root"));





            share|improve this answer















            You can simplify your code by using react-router-dom's HashRouter with React's ref.current.scrollIntoView() or window.scrollTo(ref.currrent.offsetTop).



            Currently tested and working on Chrome (desktop/android), Firefox(desktop), Silk Browser(android), Saumsung Internet(android), and Safari(iOS -- with one caveat in that it instantly jumps to the selection). While I was able to test and confirm it's working within the sandbox environment's iframe, you'll have to adapt/test it within a standalone iframe.



            I'd also like to point out that your approach is very jQuery like and that you should avoid directly attempting to utilize or manipulate the DOM and/or the window. In addition, you seem to use a lot of let variables throughout your code, but they remain unchanged. Instead, they should be a const variable as React evaluates variables each time it re-renders, so unless you plan on changing that variable during the re-render process, there's no need to use let.



            Working example: https://v6y5211n4l.codesandbox.io



            Edit ScrollIntoView on Selection




            components/ScrollBar



            import React, Component from "react";
            import PropTypes from "prop-types";
            import Helmet from "react-helmet";
            import Select from "react-select";
            import withRouter from "react-router-dom";
            import "./styles.css";

            const scrollOpts =
            behavior: "smooth",
            block: "start"
            ;

            class ScrollBar extends Component
            constructor(props)
            super(props);

            const titleRefs = props.searchOptions.map(
            ( label ) => (this[label] = React.createRef())
            ); // map over options and use "label" as a ref name; ex: this.orange
            this.topWindow = React.createRef();
            this.searchRef = React.createRef();
            const pathname = props.history.location.pathname.replace(///g, ""); // set current pathname without the "/"

            this.state =
            titleRefs,
            menuIsOpen: false,
            isValid: props.searchOptions.some(( label ) => label === pathname), // check if the current pathname matches any of the labels
            pathname
            ;


            componentDidMount()
            const pathname, isValid = this.state;
            if (isValid) this.scrollToElement(); // if theres a pathname and it matches a label, scroll to it
            if (!isValid && pathname) this.searchRef.current.select.focus(); // if there's a pathname but it's invalid, focus on the search bar


            // allows us to update state based upon prop updates (in this case
            // we're looking for changes in the history.location.pathname)
            static getDerivedStateFromProps(props, state)
            const nextPath = props.history.location.pathname.replace(///g, "");
            const isValid = props.searchOptions.some(( label ) => label === nextPath);
            return state.pathname !== nextPath ? pathname: nextPath, isValid : null; // if the path has changed, update the pathname and whether or not it is valid


            // allows us to compare new state to old state (in this case
            // we're looking for changes in the pathname)
            componentDidUpdate(prevProps, prevState)
            if (this.state.pathname !== prevState.pathname)
            this.scrollToElement();



            scrollToElement = () =>
            const isValid, pathname = this.state;
            const elem = isValid ? pathname : "topWindow";
            setTimeout(() =>
            window.scrollTo(
            behavior: "smooth",
            top: this[elem].current.offsetTop - 45
            );
            , 100);
            ;

            onInputChange = (options, action ) =>
            if (action === "menu-close")
            this.setState( menuIsOpen: false , () =>
            this.searchRef.current.select.blur()
            );
            else
            this.setState( menuIsOpen: true );

            ;

            onChange = ( value ) =>
            const history = this.props;
            if (history.location.pathname.replace(///g, "") !== value) // if the select value is different than the previous selected value, update the url -- required, otherwise, react-router will complain about pushing the same pathname/value that is current in the url
            history.push(value);

            this.searchRef.current.select.blur();
            ;

            onFocus = () => this.setState( menuIsOpen: true );

            render()
            const pathname, menuIsOpen, titleRefs = this.state;
            const searchOptions, styles = this.props;

            return (
            <div className="container">
            <Helmet title= "Select an option" />
            <div className="heading">
            <Select
            placeholder="Search..."
            isClearable=true
            isSearchable=true
            options=searchOptions
            defaultInputValue=pathname
            onFocus=this.onFocus
            onInputChange=this.onInputChange
            onChange=this.onChange
            menuIsOpen=menuIsOpen
            ref=this.searchRef
            value=null
            styles=
            />
            </div>
            <div className="fruits-list">
            <div ref=this.topWindow />
            searchOptions.map(( label, value , key) => (
            <div key=value id=value>
            <p ref=titleRefs[key]>label</p>
            [1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14].map(num => (
            <p key=num>num</p>
            ))
            </div>
            ))
            </div>
            </div>
            );



            ScrollBar.propTypes =
            searchOptions: PropTypes.arrayOf(
            PropTypes.shape(
            label: PropTypes.string.isRequired,
            value: PropTypes.string.isRequired
            ).isRequired
            ).isRequired,
            styles: PropTypes.objectOf(PropTypes.func)
            ;

            export default withRouter(ScrollBar);


            index.js



            import React from "react";
            import render from "react-dom";
            import HashRouter from "react-router-dom";
            import Helmet from "react-helmet";
            import ScrollBar from "../src/components/ScrollBar";

            const config =
            htmlAttributes: lang: "en" ,
            title: "My App",
            titleTemplate: "Scroll Search - %s",
            meta: [

            name: "description",
            content: "The best app in the world."

            ]
            ;

            const searchOptions = [

            label: "apple",
            value: "apple"
            ,

            label: "orange",
            value: "orange"
            ,

            label: "banana",
            value: "banana"
            ,

            label: "strawberry",
            value: "strawberry"

            ];

            const styles =
            menu: base => ( ...base, width: "100%", height: "75vh" ),
            menuList: base => ( ...base, minHeight: "75vh" ),
            option: base => ( ...base, color: "blue" )
            ;

            const App = () => (
            <HashRouter>
            <Helmet ...config />
            <ScrollBar searchOptions=searchOptions styles=styles />
            </HashRouter>
            );

            render(<App />, document.getElementById("root"));






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 27 at 3:40

























            answered Mar 25 at 22:44









            Matt CarlottaMatt Carlotta

            4,0161714




            4,0161714












            • That's great, thanks. It handles well the case when a valid value is provided but I also want to handle when an invalid one is. I clarified the details above and started work on a modification of your solution here codesandbox.io/s/xl46pnmr8p

              – Dan Cancro
              Mar 26 at 17:18











            • Updated answer above. Also, the setTimeout is required for mobile browsers. Otherwise, it won't scroll.

              – Matt Carlotta
              Mar 26 at 18:23











            • Just finished. It works on my computer but it doesn't work in Safari on my iPhone. It will scroll to the correct spot on load but the Search box disappears. If you manually swipe all the way back up, and then swipe one more time, the box comes back. The Search box stays put if you manually scroll but scrollIntoView() does not work on this device. Please try this on mobile: v6y5211n4l.codesandbox.io/#/orange

              – Dan Cancro
              Mar 27 at 1:38











            • Updated answer. That's a problem with mobile not liking overflow: hidden; on the body and position: absolute; on the Select component. Instead, set .heading as position: fixed; width: 100%; and remove the overflow: hidden;. As such, you'll have to use an window.scrollTo() with an offsetTop calculation, which will scroll to the correct location (since a fixed position floats above, you'll have to offset it, otherwise it'll land directly on top of the ref). In addition, another drawback is that when using the back button it immediately jumps to the last selected location.

              – Matt Carlotta
              Mar 27 at 3:19












            • No matter which direction you take, ref.scrollIntoView() or window.scrollTo() you're going to run into browser limitations.

              – Matt Carlotta
              Mar 27 at 3:22

















            • That's great, thanks. It handles well the case when a valid value is provided but I also want to handle when an invalid one is. I clarified the details above and started work on a modification of your solution here codesandbox.io/s/xl46pnmr8p

              – Dan Cancro
              Mar 26 at 17:18











            • Updated answer above. Also, the setTimeout is required for mobile browsers. Otherwise, it won't scroll.

              – Matt Carlotta
              Mar 26 at 18:23











            • Just finished. It works on my computer but it doesn't work in Safari on my iPhone. It will scroll to the correct spot on load but the Search box disappears. If you manually swipe all the way back up, and then swipe one more time, the box comes back. The Search box stays put if you manually scroll but scrollIntoView() does not work on this device. Please try this on mobile: v6y5211n4l.codesandbox.io/#/orange

              – Dan Cancro
              Mar 27 at 1:38











            • Updated answer. That's a problem with mobile not liking overflow: hidden; on the body and position: absolute; on the Select component. Instead, set .heading as position: fixed; width: 100%; and remove the overflow: hidden;. As such, you'll have to use an window.scrollTo() with an offsetTop calculation, which will scroll to the correct location (since a fixed position floats above, you'll have to offset it, otherwise it'll land directly on top of the ref). In addition, another drawback is that when using the back button it immediately jumps to the last selected location.

              – Matt Carlotta
              Mar 27 at 3:19












            • No matter which direction you take, ref.scrollIntoView() or window.scrollTo() you're going to run into browser limitations.

              – Matt Carlotta
              Mar 27 at 3:22
















            That's great, thanks. It handles well the case when a valid value is provided but I also want to handle when an invalid one is. I clarified the details above and started work on a modification of your solution here codesandbox.io/s/xl46pnmr8p

            – Dan Cancro
            Mar 26 at 17:18





            That's great, thanks. It handles well the case when a valid value is provided but I also want to handle when an invalid one is. I clarified the details above and started work on a modification of your solution here codesandbox.io/s/xl46pnmr8p

            – Dan Cancro
            Mar 26 at 17:18













            Updated answer above. Also, the setTimeout is required for mobile browsers. Otherwise, it won't scroll.

            – Matt Carlotta
            Mar 26 at 18:23





            Updated answer above. Also, the setTimeout is required for mobile browsers. Otherwise, it won't scroll.

            – Matt Carlotta
            Mar 26 at 18:23













            Just finished. It works on my computer but it doesn't work in Safari on my iPhone. It will scroll to the correct spot on load but the Search box disappears. If you manually swipe all the way back up, and then swipe one more time, the box comes back. The Search box stays put if you manually scroll but scrollIntoView() does not work on this device. Please try this on mobile: v6y5211n4l.codesandbox.io/#/orange

            – Dan Cancro
            Mar 27 at 1:38





            Just finished. It works on my computer but it doesn't work in Safari on my iPhone. It will scroll to the correct spot on load but the Search box disappears. If you manually swipe all the way back up, and then swipe one more time, the box comes back. The Search box stays put if you manually scroll but scrollIntoView() does not work on this device. Please try this on mobile: v6y5211n4l.codesandbox.io/#/orange

            – Dan Cancro
            Mar 27 at 1:38













            Updated answer. That's a problem with mobile not liking overflow: hidden; on the body and position: absolute; on the Select component. Instead, set .heading as position: fixed; width: 100%; and remove the overflow: hidden;. As such, you'll have to use an window.scrollTo() with an offsetTop calculation, which will scroll to the correct location (since a fixed position floats above, you'll have to offset it, otherwise it'll land directly on top of the ref). In addition, another drawback is that when using the back button it immediately jumps to the last selected location.

            – Matt Carlotta
            Mar 27 at 3:19






            Updated answer. That's a problem with mobile not liking overflow: hidden; on the body and position: absolute; on the Select component. Instead, set .heading as position: fixed; width: 100%; and remove the overflow: hidden;. As such, you'll have to use an window.scrollTo() with an offsetTop calculation, which will scroll to the correct location (since a fixed position floats above, you'll have to offset it, otherwise it'll land directly on top of the ref). In addition, another drawback is that when using the back button it immediately jumps to the last selected location.

            – Matt Carlotta
            Mar 27 at 3:19














            No matter which direction you take, ref.scrollIntoView() or window.scrollTo() you're going to run into browser limitations.

            – Matt Carlotta
            Mar 27 at 3:22





            No matter which direction you take, ref.scrollIntoView() or window.scrollTo() you're going to run into browser limitations.

            – Matt Carlotta
            Mar 27 at 3:22











            -1














            You can use https://www.npmjs.com/package/element.scrollintoviewifneeded-polyfill.



            As soon as possibile in your application import the library



            import 'element.scrollintoviewifneeded-polyfill';


            Than you can use the method scrollIntoViewIfNeeded(); on all the dom nodes.
            The library will polyfill the method so you could use this on all browsers.



            I recommend you to use this with a react ref so you don't have to call getElementById or other document method in order to retrieve the dom node.



            const ref = React.createRef();
            <div id="somevalue" ref=ref />


            Than in your componentDidMount you can use the same method you describe for retrieving the id of the div you want to scroll in, get the associated ref and call



             ref.current.scrollIntoViewIfNeeded();


            Where the ref is the right div reference, you can obviously store all the ref in a map and than retrieve in your components methods.






            share|improve this answer

























            • Thanks. Unfortunately it is still doing it. It jumps to the right place, then jumps back to the top. github.com/dancancro/questions/blob/nodiv/src/client/components/…

              – Dan Cancro
              Mar 22 at 17:44















            -1














            You can use https://www.npmjs.com/package/element.scrollintoviewifneeded-polyfill.



            As soon as possibile in your application import the library



            import 'element.scrollintoviewifneeded-polyfill';


            Than you can use the method scrollIntoViewIfNeeded(); on all the dom nodes.
            The library will polyfill the method so you could use this on all browsers.



            I recommend you to use this with a react ref so you don't have to call getElementById or other document method in order to retrieve the dom node.



            const ref = React.createRef();
            <div id="somevalue" ref=ref />


            Than in your componentDidMount you can use the same method you describe for retrieving the id of the div you want to scroll in, get the associated ref and call



             ref.current.scrollIntoViewIfNeeded();


            Where the ref is the right div reference, you can obviously store all the ref in a map and than retrieve in your components methods.






            share|improve this answer

























            • Thanks. Unfortunately it is still doing it. It jumps to the right place, then jumps back to the top. github.com/dancancro/questions/blob/nodiv/src/client/components/…

              – Dan Cancro
              Mar 22 at 17:44













            -1












            -1








            -1







            You can use https://www.npmjs.com/package/element.scrollintoviewifneeded-polyfill.



            As soon as possibile in your application import the library



            import 'element.scrollintoviewifneeded-polyfill';


            Than you can use the method scrollIntoViewIfNeeded(); on all the dom nodes.
            The library will polyfill the method so you could use this on all browsers.



            I recommend you to use this with a react ref so you don't have to call getElementById or other document method in order to retrieve the dom node.



            const ref = React.createRef();
            <div id="somevalue" ref=ref />


            Than in your componentDidMount you can use the same method you describe for retrieving the id of the div you want to scroll in, get the associated ref and call



             ref.current.scrollIntoViewIfNeeded();


            Where the ref is the right div reference, you can obviously store all the ref in a map and than retrieve in your components methods.






            share|improve this answer















            You can use https://www.npmjs.com/package/element.scrollintoviewifneeded-polyfill.



            As soon as possibile in your application import the library



            import 'element.scrollintoviewifneeded-polyfill';


            Than you can use the method scrollIntoViewIfNeeded(); on all the dom nodes.
            The library will polyfill the method so you could use this on all browsers.



            I recommend you to use this with a react ref so you don't have to call getElementById or other document method in order to retrieve the dom node.



            const ref = React.createRef();
            <div id="somevalue" ref=ref />


            Than in your componentDidMount you can use the same method you describe for retrieving the id of the div you want to scroll in, get the associated ref and call



             ref.current.scrollIntoViewIfNeeded();


            Where the ref is the right div reference, you can obviously store all the ref in a map and than retrieve in your components methods.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 22 at 21:41









            marc_s

            586k13011281273




            586k13011281273










            answered Mar 22 at 16:18









            CoogleCoogle

            4929




            4929












            • Thanks. Unfortunately it is still doing it. It jumps to the right place, then jumps back to the top. github.com/dancancro/questions/blob/nodiv/src/client/components/…

              – Dan Cancro
              Mar 22 at 17:44

















            • Thanks. Unfortunately it is still doing it. It jumps to the right place, then jumps back to the top. github.com/dancancro/questions/blob/nodiv/src/client/components/…

              – Dan Cancro
              Mar 22 at 17:44
















            Thanks. Unfortunately it is still doing it. It jumps to the right place, then jumps back to the top. github.com/dancancro/questions/blob/nodiv/src/client/components/…

            – Dan Cancro
            Mar 22 at 17:44





            Thanks. Unfortunately it is still doing it. It jumps to the right place, then jumps back to the top. github.com/dancancro/questions/blob/nodiv/src/client/components/…

            – Dan Cancro
            Mar 22 at 17:44

















            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55303221%2fhow-to-scroll-a-react-page-when-it-loads%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

            용인 삼성생명 블루밍스 목차 통계 역대 감독 선수단 응원단 경기장 같이 보기 외부 링크 둘러보기 메뉴samsungblueminx.comeh선수 명단용인 삼성생명 블루밍스용인 삼성생명 블루밍스ehsamsungblueminx.comeheheheh

            155 수학 과학 기타 둘러보기 메뉴eh추가해eh문서를 완성해