1

I have a trouble with correct routing in React project. When I go into "Heroes" route, there is a list of "heroes" (this is a blog). I can open a document by id-made link. When I open the document, and then click on "Heroes", it is not rendered. It will render if I only the first open the main page or "about", and then open "Heroes". Maybe someone can tell me, how to fix this, looking at the code below. Will be very grateful for any help!

App.jsx

import React, { Component } from 'react';
import { BrowserRouter, Switch, Route, Link } from 'react-router-dom';
import Heroes from './components/Heroes';
import About from './components/About';

class App extends Component {
  render() {
    return (
      <BrowserRouter>
        <>
          <Header />
          <div className="container">
            <Switch>
              <Route path="/" exact component={Home} />
              <Route path="/heroes" component={Heroes} />
              <Route path="/about" component={About} />
            </Switch>
          </div>
        </>
      </BrowserRouter>
    );
  }
}

const Header = () => (
  <nav>
    <div className="container">
      <div className="nav-wrapper">
        <Link to="/" className="brand-logo">
          <i className="material-icons">home</i>
        </Link>
        <ul id="nav-mobile" className="right hide-on-med-and-down">
          <li>
            <Link to="/heroes">Heroes</Link>
          </li>
          <li>
            <Link to="/about">About</Link>
          </li>
        </ul>
      </div>
    </div>
  </nav>
);

const Home = () => (
  <>
    <h3>Fullstack Express-Apollo-React</h3>
  </>
);

export default App;

Heroes.jsx

import React, { Component } from 'react';
import { BrowserRouter, Switch, Route, Link } from "react-router-dom";
import Hero from './Hero';

const mockData = {
  "heroes": [
    {
      "_id": "5db31d0c5419031a7c8d749c",
      "title": "qqqqqqqqqqqqqqq",
      "description": "ljlkjlkjlkj",
      "date": "1572019076651"
    },
    {
      "_id": "5db331e25419031a7c8d749d",
      "title": "gfdgfdhgfdhgfdgf",
      "description": "yuytruytrytryt",
      "date": "1572019076651"
    },
    {
      "_id": "5db332405419031a7c8d749e",
      "title": "mnbvmnbvmnbvnbvmn",
      "description": "eytretretretretr",
      "date": "1572019076651"
    }
  ]
}

class Heroes extends Component {
  render() {
    return (
      <div>
        <BrowserRouter>
          <Switch>
            {mockData.heroes.map(hero => (
              <Route
                exact
                path={`/heroes/${hero._id}`}
                render={() => <Hero data={hero} />}
              />
            ))}
            <Route
              exact
              path="/heroes"
              component={Home}
            />
          </Switch>
        </BrowserRouter>
      </div>
    );
  }
}

const Home = () => {
  return (
    <>
      {mockData.heroes.map(hero => (
        <div key={hero._id}>
          <Link to={`/heroes/${hero._id}`}>
            <h3>{hero.title}</h3>
          </Link>
          <h5>{hero.description}</h5>
          <h5>{hero.date}</h5>
        </div>
      ))}
    </>
  );
};

export default Heroes;

Hero.jsx

import React, { Component } from 'react';

class Hero extends Component {
  render() {
    return (
      <>
        <h5>{this.props.data.title}</h5>
        <h5>{this.props.data.description}</h5>
      </>
    );
  }
}

export default Hero;

If necessary, here is the link to github repository: react-homework

Thanks in advance!

1
  • One issue i that you add a second BrowserRouter component in the Heroes component. I guess there should be just one Router, take a look at the docu Commented Nov 6, 2019 at 10:05

2 Answers 2

0

Your Heroes component has route

    <Route
      exact
      path="/heroes"
      component={Home}
    />

that is pointing towards Home component, while in App it is pointing to Heroes <Route path="/heroes" component={Heroes} /> Could be the cause of your issue

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! Can you tell me please, how to configure it better so that the Heroes page (or blog) can be accessed both from the main page and from the page of a separate “hero” (separate post)?
There should be just one router in the app ( although there are exceptions ), and try to have all paths point to the same components in order to avoid such issues. Also, if my answer solved your problem, could you please marked it as solved
0
import React, { Component } from 'react';
import { BrowserRouter, Switch, Route, Link } from 'react-router-dom';
import About from './components/About';
import Hero from './components/Hero';

const mockData = {
  "heroes": [
    {
      "_id": "5db31d0c5419031a7c8d749c",
      "title": "qqqqqqqqqqqqqqq",
      "description": "ljlkjlkjlkj",
      "date": "1572019076651"
    },
    {
      "_id": "5db331e25419031a7c8d749d",
      "title": "gfdgfdhgfdhgfdgf",
      "description": "yuytruytrytryt",
      "date": "1572019076651"
    },
    {
      "_id": "5db332405419031a7c8d749e",
      "title": "mnbvmnbvmnbvnbvmn",
      "description": "eytretretretretr",
      "date": "1572019076651"
    }
  ]
}

class App extends Component {
  render() {
    return (
      <BrowserRouter>
        <>
          <Header />
          <div className="container">
            <Switch>
              <Route path="/" exact component={Home} />
              {mockData.heroes.map(hero => (
                <Route
                  exact
                  path={`/heroes/${hero._id}`}
                  render={() => <Hero data={hero} />}
                />
              ))}
              <Route
                exact
                path="/heroes"
                component={heroesIndex}
              />
              <Route path="/about" component={About} />
            </Switch>
          </div>
        </>
      </BrowserRouter>
    );
  }
}

const Header = () => (
  <nav>
    <div className="container">
      <div className="nav-wrapper">
        <Link to="/" className="brand-logo">
          <i className="material-icons">home</i>
        </Link>
        <ul id="nav-mobile" className="right hide-on-med-and-down">
          <li>
            <Link to="/heroes">Heroes</Link>
          </li>
          <li>
            <Link to="/about">About</Link>
          </li>
        </ul>
      </div>
    </div>
  </nav>
);

const heroesIndex = () => {
  return (
    <>
      {mockData.heroes.map(hero => (
        <div key={hero._id}>
          <Link to={`/heroes/${hero._id}`}>
            <h3>{hero.title}</h3>
          </Link>
          <h5>{hero.description}</h5>
          <h5>{hero.date}</h5>
        </div>
      ))}
    </>
  );
};

const Home = () => (
  <>
    <h3>Fullstack Express-Apollo-React</h3>
  </>
);

export default App;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.