I'm designing a simple application using create-react-app
and I've recently delved into the power of react-router
. However, I'm having an issue with pages getting stuck trying to load, and I'm not sure why.
I've got a Navbar component, for which I'll condense the gist of what it is.
import React from 'react';
import { BrowserRouter as Router, Link, Switch, Route } from 'react-router-dom';
import BlogPost from '../Pages/BlogPost';
// Condensed because a lot of the detail is unnecessary and no-one likes blocks of unneeded code
class Navbar extends React.Component {
render() {
return (
<Router>
<nav>
<div id="navigationlinks">
<ul id="navlinks-left">
<li className="nav-item"><Link to='/'>Home</Link></li>
<li className="nav-item"><Link to='/about'>About</Link></li>
</ul>
</div>
</nav>
<Switch>
<Route path='/post' component={BlogPost} />
<Route path='/about'>
<About />
</Route>
</Switch>
</Router>
);
}
}
function About() {
return <h2>The about page.</h2>;
}
export default Navbar;
BlogPost
represents a component that is a page in itself. The code looks like this. Again, I'll abstract away from the stuff that's not relevant.
import React from 'react';
import Navbar from '../Components/Navbar';
// Other components on this page. None of them reference the navbar or contain a router of their own.
import BlogBox from '../Sections/BlogBox';
import CommentForm from '../Components/CommentForm';
import CommentBox from '../Sections/CommentBox';
class BlogPost extends React.Component {
getBlogPost(address) {
// Gets blog data (like the title, description, content, image, etc.) using 'fetch' from
// an API at 'address'. Abstracted away because this isn't relevant.
}
componentDidMount() {
console.log("Blog post mounted!");
this.getBlogPost("http://localhost:8080/api/blog/samplepost");
}
render() {
return (
<div className="blog-post">
<Navbar />
<BlogBox post={this.state ? this.state.post : ""}/>
<CommentForm />
<CommentBox comments={this.state ? this.state.comments: ""} />
</div>
);
}
}
export default BlogPost;
The homepage of my application is located at '/'
. It's rendered in my index.js
file, the code of which is below.
import React from 'react';
import ReactDOM from 'react-dom';
import BlogHome from './Pages/BlogHome';
import BlogPost from './Pages/BlogPost';
ReactDOM.render(
<BlogHome />,
document.getElementById('root')
);
The homepage renders fine, but when I go to navigate to /post
, the application attempts to load the page indefinitely, and eventually times out, being unable to do so.
Notice how the BlogPost
page component renders the Navbar
component, which in turn has a path /post
which renders the BlogPost
object? I'm not sure if I'm able to change this. Could this be the reason why the /post
path can't load?
What concerns me the most here is that I eventually would like to add additional pages which will not only contain this same Navbar
, but for which their page links also exist in this Navbar. For example, if I add an About page, this page will not only contain the Navbar, but its link will also be present in this Navbar!
Is there a way I can keep such self-page links in the Navbar, without the recursive render loop occurring?
You are creating a cycle between rendering Navbar
and BlogPost
when the current path matches "/post`.
In other words BlogHome
renders a Navar
which renders a BlogPost
which then renders another Navbar
and another BlogPost
ad nauseam.
Restructure your navbar and routes a bit to split them out
index.js
Since BlogHome
sounds like a page it should be placed on its own route. Move Router
here to wrap entire app. Render BlogHome
path last as that matches all path prefixes, so it will render if no other route is matched above it by the Switch
.
ReactDOM.render(
<Router>
<Switch>
<Route path='/post' component={BlogPost} />
<Route path='/about'>
<About />
</Route>
<Route path="/" component={BlogHome} />
</Switch>
</Router>,
document.getElementById('root')
);
Navbar
Remove the router and routes, leave links only.
class Navbar extends React.Component {
render() {
return (
<nav>
<div id="navigationlinks">
<ul id="navlinks-left">
<li className="nav-item"><Link to='/'>Home</Link></li>
<li className="nav-item"><Link to='/about'>About</Link></li>
</ul>
</div>
</nav>
);
}
}
Now each page should be free to render a Navbar
or not.
try to remove Navbar in your BlogPost component, because when the location changes it will switch component here
<Switch>
<Route path='/post' component={BlogPost} />
<Route path='/about'>
<About />
</Route>
</Switch>
and
<nav>
<div id="navigationlinks">
<ul id="navlinks-left">
<li className="nav-item"><Link to='/'>Home</Link></li>
<li className="nav-item"><Link to='/about'>About</Link></li>
</ul>
</div>
</nav>
will persisit.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.