3

I learn some React-router-dom and it's kind of working but since I have three Components one after the other like a long page. Then When I click about button like this in the top menu;

<Button variant="primary" onClick={() => history.push('/articles')}>
        Articles
</Button>
<Button variant="primary" onClick={() => history.push('/stories')}>
        Stories
</Button>
<Button variant="primary" onClick={() => history.push('/about')}>
        About
</Button>

The /about page is rendered but not scrolled to because it's page number 3. Is there some way to auto scroll to the page?

My menu is not fixed but whenever user scroll up the menu appear and when user scroll down the menu is gone to not block content.

It looks like this three Components forming a long page

enter image description here

Is there maybe something built into react router or useHistory or do I have to figure out some way to make the Components know they are being summoned from main Menu? and then themselves calculate how to scroll to become visible.

I know little React Redux and was thinking I could dispatch and action from the Menu button and mapStateToProp listen for the action in the Component, that then will scroll visible. Feels like a bad hack don't know.

Or Assayag
  • 5,662
  • 13
  • 57
  • 93
Tord Larsen
  • 2,670
  • 8
  • 33
  • 76
  • 1
    I've updated my answer with other solution, pay attention that if it is a class component you need to write this.onAboutPageClick inside Button element. And scrollIntoView have a lot of options to manage scrolling behavior – Dmitriy Sakhno Nov 21 '20 at 10:29

2 Answers2

2

not sure if this works or if this consistent/best solution, but as far as here is no other answers you could try to use this

  const onAboutPageClick = () =>{
    const aboutPageNode = document.getElementById('aboutPage')

    aboutPageNode.scrollIntoView({behavior: "smooth"});
    history.push('/about')
}


<Button variant="primary" onClick={() => history.push('/articles')}>
  Articles
</Button>
<Button variant="primary" onClick={() => history.push('/stories')}>
Stories
</Button>
<Button variant="primary" onClick={onAboutPageClick}>
    About
</Button>


..... some other html code

<div id="aboutPage"> Here is about page </div>
Dmitriy Sakhno
  • 453
  • 3
  • 8
  • When I try this and on click `Button` what happens it that the the app is reloaded completely like I pressed F5 refresh. Very strange! . I removed the `onClick={() => history.push..` – Tord Larsen Nov 21 '20 at 10:13
  • But I see what you mean I did not know about this Technique will try some things. – Tord Larsen Nov 21 '20 at 10:27
  • That did it I understand and learn some cool new things thanks. Must wait 8 hour to reward you the bounty – Tord Larsen Nov 21 '20 at 10:46
  • 1
    and one more thing – Dmitriy Sakhno Nov 21 '20 at 10:50
  • I hade to remove the `history.push('/about')` because it attached another about component righter after about. so there was two about pages after each other.. Dunno seem enough to only do `aboutPageNode.scrollIntoV...` What does the history push do, is it like recording current location – Tord Larsen Nov 21 '20 at 11:02
  • 1
    Maybe you even don't need history.push('/about') if this all is on one page and you do not trace location by other functions to launch some actions. Not sure enough, I'm not a big expert in react-router – Dmitriy Sakhno Nov 21 '20 at 11:11
  • 2
    @TordLarsen While this answer' is correct, I'd advice to use [Refs](https://reactjs.org/docs/refs-and-the-dom.html) instead of _document.getElemetById_ as discussed here [refs vs getelementbyid](https://stackoverflow.com/questions/37273876/reactjs-this-refs-vs-document-getelementbyid/37274379) and Yes, you don't need React-router-dom to do so unless you want that on other pages. – awran5 Nov 21 '20 at 15:14
  • about refs, I read the answer in that link like "you can only access the refs in the context where you define it", I read the refs docs and are sure it can be used in my case? – Tord Larsen Nov 21 '20 at 17:23
  • 1
    @TordLarsen Yes, check this [sandbox](https://codesandbox.io/s/zen-perlman-8uz4q) – awran5 Nov 21 '20 at 18:24
  • thanks for the Sandbox but I cant understand how to apply this in my case, how can I send the `ref` from `aboutPage` to where I need to run the `sectionRef.current.scrollIntoView(..` I mean The `aboutPage` is created elsewhere. Anyway it's working as is and I'm happy learning new things – Tord Larsen Nov 21 '20 at 22:32
1

in the the answer above said by Dmitriy Sakhno it gives an error I think because it cann't find it because the page haven't render yet so I used setTimeout and it worked.

const onAboutPageClick = () => {
    history.push('/about')
    setTimeout(() => {
      const aboutPageNode = document.getElementById('aboutPage');
      aboutPageNode.scrollIntoView({behavior: "smooth"});
    }, 0);
}
Dream Echo
  • 165
  • 2
  • 8