bluebrooklynbrim
bluebrooklynbrim

Reputation: 277

Render nested route component on new page

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

Answers (1)

kucukharf
kucukharf

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

Related Questions