Reputation: 277
I want to be able to have a Portfolio page (example.com/portfolio), and a dynamic route for individual case studies (example.com/portfolio/case-study/dynamic-url-slug). Currently, the new component that should render in its own page is still rendering within the page (understandable, as the markup declares the route within the containing div). But how do I get it to render on its own page?
App.js (where all routes are declared)
import React, { Component } from 'react';
import { Switch, Route } from 'react-router-dom';
import Home from './components/Pages/Home/Home';
import About from './components/Pages/About/About';
import Portfolio from './components/Pages/Portfolio/Potfolio';
import CaseStudy from './components/Pages/Portfolio/CaseStudyPage';
export default class App extends Component {
render() {
return (
<div className="icon-container" id="outer-container">
<div className="pages">
<Switch>
<Route exact path='/' component={ Home } />
<Route path='/about' component={ About } />
<Route path='/portfolio' component={ Portfolio } />
<Route exact path={`/portfolio/case-study/:caseSlug`}
render={(props) => <CaseStudy />} />
</Switch>
</div>
</div>
)
}
}
Portfolio.js
import React, { Component } from 'react';
import '../styles/vendor/swiper/swiper.min.css';
import Swiper from 'react-id-swiper';
import { Link, Route } from 'react-router-dom';
import CaseStudyPage from './Pages/Work/CaseStudyPage';
const case_studiesURL = "http://myprivateblogapi.com/wp-json/wp/v2/case_studies?_embed";
const case_URL = '/portfolio/case-study/';
export default class Portfolio extends Component {
constructor(props) {
super(props);
this.state = {
case_studies: [],
isLoading: true,
requestFailed: false
}
}
componentDidMount() {
fetch(case_studiesURL)
{/* fetching all the appropriate data */}
}
renderPortfolioItem(data) {
return props => <CaseStudyPage data={data} {...props} />
}
render() {
if(this.state.isLoading) return <span>Loading...</span>
const params = {
{/* swiper parameters */}
}
let case_studies_items = this.state.case_studies.map((case_studies_item, index) => {
return (
<div className="portfolio-slide" id={`swiper-slide-${index}`}
key={index}
>
<Link className="portfolio-link"
to={`${case_URL}${case_studies_item.slug}`}>
<h3 className="portfolio-swiper--slide-title"> {case_studies_item.title.rendered}</h3>
</Link>
<Route exact path={`${case_URL}:caseSlug`}
render={this.renderPortfolioItem(case_studies_item)} />
</div>
)
});
return(
<div className="portfolio-swiper--container">
<Swiper {...params}>
{case_studies_items}
</Swiper>
</div>
)
}
}
Upvotes: 1
Views: 981
Reputation: 110
You should define a route for each different views in react router,
<Switch>
<Route exact path='/' component={ Home } />
<Route exact path='/about' component={ About } />
<Route exact path='/portfolio' component={ Portfolio } />
<Route exact path='/portfolio/case-study' component={ CaseStudy } />
<Route exact path='/portfolio/case-study/:caseSlug' component {CaseStudyDetails} />
</Switch>
and you don't need to create a render method to pass props to your view components. You can easily reach router props inside of a react component if it is already rendered into Router,
this.props.match
this.props.location
this.props.history
as an example you can get your dynamic parameter inside of CaseStudy component like,
this.props.match.caseSlug
Upvotes: 1