Navigation within section of a page using react router - javascript

I have my navigation bar with following contents
+------+-------+-------+
| Home | About | Login |
+------+-------+-------+
Home is vertically scroll-able page with multiple sections (e.g #About and other sections) While login is separate react component which gets rendered on /login route.
Here is my route.js file
<Route path="/" component={App}>
<IndexRoute component={Home}/>
<Route path="/login" component={Login}/>
</Route>
My question is how should I handle navigational changes within page sections?
Currently I am doing it like this:
<li>
<Link to="/#about-us">About</Link>
</li>
and About section within home page is
<div id="about-us">
About us
</div>
Problem with this approach is when I am at login page(/login) and click on About section link (/#about-us) of Home page nothing happens!
Edit:
I am using react-routerV2

React Router currently does not handle scroll behavior for hash anchors.
However, if you're using browser history, in your case, you can just use <a href="#about-us">, and let the browser take care of it.

I've run into the same problem! The fix I'm using is below...
animatedScroll: function(div_to_scroll_to) {
jQuery('html, body').animate({
scrollTop: div_to_scroll_to.offset().top
}, 500);
}
Clicking the About link should trigger an onClick event which calls animatedScroll with the div you want to scroll to (which is a jQuery element in the above code) as the parameter.
This avoids page reloads (which is how the <a href="..." ... fix would work) and requires very little work on your part.
Hopefully the React-Router team will have built handlers for intra-component navigation soon.
Good luck!
Note: Depending on how your page is structured jQuery('html, body') may not be appropriate. This should always just be the parent container. Please let me know if you have any further questions.

Related

When adding multiple pages with Routes, why do all of my pages load at once when I'm on my "homepage"

I'm relatively somewhat new to the whole world of react, DOM, etc.
This probably sounds like a simple issue or a dumb question, bear with me.
My code for the routing stuff looks like:
function App() {
return (
<div className="content">
<SideBar>
<Router>
<Routes>
<Route path="/dashboard" element={Dashboard} />
</Routes>
</Router>
</SideBar>
</div>
);
}
export default App;
My SideBar is a component of a sidebar, it should allow users to click on a button and to navigate to a new page. In this case, a dashboard. However, all pages basically load at the start of me going to my localhost/
I've tested this out due to a console.log loading from the dashboard basically popping up in other places, not just localhost/dashboard.
I'm using MaterialUI, React.
My SideBar.js looks like this:
<List>
{BarData.map((item, key) => {
return (
<ListItemButton
key={key}
onClick={() => {
window.location.pathname = item.link;
}}
Has things removed, but here is my SideBar data (in another folder).
export const BarData = [
{
text: "Dashboard",
icon: <HomeRounded color="#637381" />,
link: "/dashboad",
},
Am I doing something wrong here? I'm completely new to React, DOM, etc. So I'm unsure if this is the best way to go in general.
In short, what I'm trying to achieve is:
Have multiple pages, if a user clicks a button, it'll navigate them to that specific page, in this case a Dashboard.
Not have every page load at once(?) I'm still unsure on why this is, is it due to me importing the dashboard page and the element is grabbing it, not working fully, so it's just loading what the page shows?

Scroll to element when redirected using <Link> React

I have this code which redirects to a component when clicked,
<Link to="/dashboard" component={Dashboard}>
Click Here
</Link>
Clicking on this takes me to the Dashboard component but I want it to scroll down automatically to a particular element in the Dashboard component.
How do I achieve this?
Simply, on the element in /dashboard define an ID.
Then when redirecting use:
<Link to="/dashboard#id-of-the-element" component={Dashboard}>
Click Here
</Link>
This will then scroll down the page to where that element is defined

ReactJs applying javascript correctly

I have 3 pages reactjs application with a bootstrap template. I am using react-router to handle the page transitions.
So I have a index.js file containing something like:
function App() {
return(
<Router>
<Switch>
<Route path="/page1/">
<Page1 />
</Route>
<Route path="/page2">
<Page2 />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</Router>
);
}
In my index.html file, I defined some js functions to apply some effects to the pages, like a carousel and things like this. The weird thing is that when I reach page2 from clicking the link on page1 the js effects are applied, but when I refresh it the js effects are not applied...
this is my page2 file (I stripped all the unnecessary stuff for simplicity):
function Page2(){
useEffect(() => {
window.applyEffects();
})
return(
some jsx here...
)
}
am I doing something wrong here?
EDIT
I realised I forgot to add an important detail. I removed the useEffect and the call to window.applyEffects() in my component and the page renders as I would expect without the effect. If then I call window.applyEffects() from the developer console everything works fine. I suspect I should find a way to call the js function AFTER the page has been totally rendered. Is this doable?
SOLVED
I would like to thank everyone that replied and helped me in the right direction. I solved it by updating the useEffect hook like this:
useEffect(() => {
const script = document.createElement('script');
script.src = `${window.location.origin}/js/effects.js`;
script.async = true;
document.body.appendChild(script);
return () => {
document.body.removeChild(script);
}
});
I created a file called effects.js in the js folder, and I load it by appending it to the dom every time the component loads... also I remember to remove it with the return. I leave this here hoping it could help someone in my same situation in the future!
Thank you stackoverflow community !
I saw that you are using window object inside your code. Maybe that is the root of your problem. On the official documentation it says:
Window Object The window object represents an open window in a
browser.
If a document contain frames ( tags), the browser creates one
window object for the HTML document, and one additional window object
for each frame.
...which kind of suggests that it will fire once the window is open in the browser, hence I'm not sure that it will re-fire once you refresh the page. Having the useEffect hook should fire away anything when a page refreshes because it mounts the component again.
I suggest look into how you are using the window.applyEffects(). Here's a link to the official window documentation.
It seems that you just want to run a piece of code every time page is reloaded, checking it out I found it
React | How to detect Page Refresh (F5)
and it seems what you are looking for.

How to let React Router render only when navigated to

I have the follow routes in my landing page.
...
<Route exact path='/MainPage' render={(match, history) => {
return <MainPage></MainPage>
}}/>
<Route exact path='/Search' render={(match, history) => {
return <SearchPage></SearchPage>
}}/>
<Route exact path='/Register' render={(match, history) => {
return <RegisterPage></RegisterPage>
}}></Route>
<Route exact path='/HTTP' render={(match, history) => {
return <HTTPPage></HTTPPage>
}}></Route>
...
The problem I'm having is that these pages are rendered immediately when the landing page is opened, which means all the css files in these routes are rendered too. For example, in the SearchPage/index.js I have:
import '../style_sheets/mainComponents.css'
When I open the browser inspector on the landing page I see all of these css files are rendered as style tags in the . A lot of these css files have class selectors which adversely modify how things look on the landing page. Is there a way to suppress the rendering of these routes or simply somehow separate the imported css in the children elements from their parent page?

Load new component while adding href to url

I am trying to implement a system to when an item in the navbar is clicked it loads a new component on the screen. I am running into a problem making this a new URL and keeping my state. Let me clarify.
Here is my navbar code:
<Nav pullRight activeKey="1" onSelect={k => this.handleSelect(k)}>
<NavItem eventKey={1} href={'/component1'}>
Component 1
</NavItem>
<NavItem eventKey={2} href={'/component2'}>
Component 2
</NavItem>
</Nav>
Here is my handleSelect code:
handleSelect(eventKey, event) {
this.setState({
componentToLoad: eventKey
});
event.preventDefault();
}
In my render I do this:
render() {
if(this.state.componentToLoad === 'component1'){
return (<Component1/>);
} else if(this.props.componentToLoad === 'component2'){
return (<Component2/>);
}
The problem I'm running into is because of the href adding to the URL the page reloads and I lose my state so it always loads component 1 because I set it to that in the constructor. If I remove the href it works, but the URL is not how I want it.
How do I get this to load the component I want, add to the URL, and keep the state?
Thank you
As mentioned in the comments, React Router is a good choice for your requirements.
Here's a codesandbox using React Router, simply illustrating the functionality you describe.
You could also use the browser's History API (see pushState method) to manipulate the URL directly without a page reload, although be aware that there are some differences in the api in modern browsers.

Categories

Resources