I am learning router and redux. I am trying to create a blog. Now the post ID route is showing up in other components like About and portfolio but not in home page because I have made it an exact path.
https://github.com/chiranjeebhub/router-redux
import React, { Component } from "react";
import { connect } from "react-redux";
class Post extends Component {
render() {
const post = this.props.post ? (
<div>
<h4>{this.props.post.title}</h4>
<p>{this.props.post.body}</p>
</div>
) : (
<div>
<p>loading post ... </p>
</div>
);
return <div>{post}</div>;
}
}
const mapStateToProps = (state, ownProps) => {
let id = ownProps.match.params.post_id;
return {
post: state.posts.find(post => post.id == id)
};
};
export default connect(mapStateToProps)(Post);
import React, { Component } from "react";
import { BrowserRouter, Route } from "react-router-dom";
import NavBar from "./Components/NavBar";
import Home from "./Components/Home";
import About from "./Components/About";
import Post from "./Components/post";
import Portfolio from "./Components/portfolio";
class App extends Component {
render() {
return (
<BrowserRouter>
<div className="App">
<NavBar />
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/portfolio" component={Portfolio} />
<Route path="/:post_id" component={Post} />
</div>
</BrowserRouter>
);
}
}
export default App;
import React, { Component } from "react";
class About extends Component {
render() {
return (
<div>
<h1>About Me</h1>
</div>
);
}
}
export default About;
const initState = {
posts: [
{ id: "1", title: "title1", body: "body1" },
{ id: "2", title: "title2", body: "body2" },
{ id: "3", title: "title3", body: "body3" },
{ id: "4", title: "title4", body: "body4" }
]
};
const rootReducer = (state = initState, action) => {
return state;
};
export default rootReducer;
Now when I load "About" component the "Loading Posts..." shows up from post.js
You are having issue because the path
<Route path="/:post_id" component={Post} />
shows that a dynamic value is expected at the post_id
placeholder. As post_id
is just a placeholder using about
, portfolio
, 1
, etc as route parameters will satisfy the condition.
i.e
// All of them are valid
/about
/portfolio
/1
So Post
component shows up along with other components.
Therefore you should wrap Route
components with Switch
Component. As Switch
component only renders the first child that matches the path so Post
component will not show up when /about
and /portfolio
is used.
import { BrowserRouter, Route, Switch } from 'react-router-dom';
<BrowserRouter>
<div className="App">
<NavBar />
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/portfolio" component={Portfolio} />
<Route path="/:post_id" component={Post} />
</Switch>
</div>
</BrowserRouter>