I am beginning to work with React and I have an issue understanding how to make react-router work.
In my project, I created an App.js file that exports a simple render function:
export default class App extends React.Component {
render () {
return <Router>
<div>
<Link to="/connected">Login</Link>
<Link to="/">Home</Link>
<Route path="/connected" component={Connected}/>
<Route exact path="/" component={LoginPage}/>
</div>
</Router>
}
}
Of course, on the top of the file, I import two components: Connected and LoginPage and a bunch of other components:
import React from 'react'
import {
HashRouter as Router,
Route,
Link
} from 'react-router-dom'
import LoginPage from './pages/LoginPage'
import Connected from './pages/Connected'
My components are quite simple:
import React from 'react'
export default class LoginPage extends React.Component {
render () {
return <div>
Hello World 1
</div>
}
}
And pretty much the same for the second component.
My problem is:
When I click on a <Link to="/">Home</Link>, the page is not updated with the LoginPage component. But if I refresh the page, the LoginPage components appears. If I click on <Link to="/connected">Login</Link>, the router does not update the page and I also need to refresh completely the page to display the right component.
What am I doing wrong? What other informations would you need to help me resolve my problem?
Copy this into 'Package.json' > 'dependencies': "react-router": "^2.4.0",
Then do npm install
Once done this:
Try this:
First Component (Routes, it is App.jsx) (Maybe you need to change routes of imports)
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, browserHistory, Redirect } from 'react-router';
import LoginPage from './pages/LoginPage'
import Connected from './pages/Connected'
ReactDOM.render(
<Router history={browserHistory}>
<Route path="/" component={LoginPage}/>
<Route path="/connected" component={Connected}/>
</Router>
, document.getElementById('root')
);
Second component (Home):
import React from 'react';
import { Link } from 'react-router';
export default class Home extends React.Component {
render() {
return(
<div>
<h1> This is HomePage </h1>
<h3> Click to go HomePage </h3>
<Link to="/">Home</Link>
<h3> Click to go Connected </h3>
<Link to="/connected">Connected</Link>
</div>
)
}
}
Third component (Connected):
import React from 'react';
import { Link } from 'react-router';
export default class Connected extends React.Component {
render() {
return(
<div>
<h1> This is ConnectedPage </h1>
<h3> Click to go HomePage </h3>
<Link to="/">Home</Link>
<h3> Click to go Connected </h3>
<Link to="/connected">Connected</Link>
</div>
)
}
}
Related
Good evening to all. I am new to ReactJS and I do not understand how I can load different content per page and at the same time have some fixed sections such as the header ( after click a LINK ).
I have created three components and I render them to the homepage.When I click the about link I would like to load Header & Learn.js component ONLY. How can I manage that?
Thanks a lot!
index.js
import React from "react";
import ReactDOM from "react-dom";
import Header from './components/header'
import MiddleMan from './components/middleman'
import BottomHero from './components/bottomhero'
import './web.css';
function App(){
return (
<React.Fragment>
<Header />
<MiddleMan />
<BottomHero />
</React.Fragment>
);
}
ReactDOM.render(<App />, document.querySelector(".container"));
middleman.js
import React, { Component } from 'react';
import Learn from './learn';
import {
BrowserRouter as Router,
Routes,
Route,
Link,
} from "react-router-dom";
class MiddleMan extends React.Component {
render() {
return (
<div className="middle JV--row JV--a--center JV--spacer">
<Router>
<ul>
<li><Link to="about">ABOUT ME</Link></li>
<li><Link to="project">PROJECTS</Link></li>
<li><Link to="exp">PR. LANGUAGES / TECHNOLOGIES</Link></li>
</ul>
<Routes>
<Route path="about" element={<Learn/>}></Route>
</Routes>
</Router>
</div>
);
}
}
export default MiddleMan;
learn.js
import React from 'react';
import Header from './header'
class Learn extends React.Component {
render(){
return (
<h2>BBBBBBBBBBBBBBBBBB</h2>
);
}
}
export default Learn;
Your app structure is a little weird considering how react-router-dom is meant to be used. I'd suggest you read their documentation!
Now, trying to give a more specific answer, you should wrap your App component in a BrowserRouter. Your routes could be inside a Switch component and to implement this Header behavior that you wish to achieve I suggest you check the answers to this question.
I'm writing my first React app, in Typescript.
Following a tutorial, I've created a single <Link> that references a single <Route> all inside my <Router> component. When I click the Link in my browser, the URL changes, but the Route does not render. I cannot figure out why the Route does not render. I've read a bunch of SO questions, but they're all related to advanced uses of Router; I can't get the most basic usecase to work.
Here's my top-level component:
import React, {Component} from 'react';
import {BrowserRouter as Router, Route, Link} from "react-router-dom";
import {StaticComponent} from "./StaticComponent/StaticComponent";
export default class App extends Component{
render() {
return (
<div className="App">
<Router>
<header className="App-header">
<span>header</span>
<Link to="/staticComponent">Static Component</Link>
</header>
<main>
<span>body</span>
<Route path="/staticComponent" element={StaticComponent}/>
</main>
</Router>
</div>
);
};
}
Here's StaticComponent:
import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom'
export function StaticComponent () {
return (
<h2>You are at Static Component</h2>
);
};
As you can see, top-level component displays as you'd expect:
But when I click the link, the StaticComponent does not display:
Is there some small detail I'm getting wrong here? Thanks!
I never figured out how to use the "element" attribute on the <Route> element, nor the "component" attribute that #gbalduzzi mentioned. However, implementing App.tsx in the following way does work:
import React, {Component} from 'react';
import {BrowserRouter as Router, Route, Link} from 'react-router-dom';
import {StaticComponent} from "./StaticComponent/StaticComponent";
export default class App extends Component<{}, {}>{
render() {
return (
<div className="App">
<Router>
<header className="App-header">
<span>header</span>
<Link to="/staticComponent">Static Component</Link>
</header>
<main>
<span>body</span>
<Route path="/staticComponent">
<StaticComponent />
</Route>
</main>
</Router>
</div>
);
};
}
Also, line 2 of StaticComponent.tsx seems to have been unnecessary; I have since taken it out.
Finally, make sure you're using the correct version of React Router. The JSX files that work for React Router 5 do not seem to work for React Router 6.
I have a homepage with a link to a form, like this:
import React, { Component } from 'react';
import {
BrowserRouter as Router,
Route,
NavLink,
Redirect,
Switch,
withRouter
} from "react-router-dom";
import addHand from './Forms/addHand'
export class Home extends Component {
render() {
return (
<div>
<Router>
<div>
<NavLink to= '/hands/new'> Add a new hand </NavLink>
<Route path= '/hands/new' component={addHand}/>
<h4> Search For Hands By Category </h4>
<h4> Search For Sessions By Category </h4>
<h4> Search For Tables By Category </h4>
</div>
</Router>
</div>
);
}
}
export default Home;
I also have a navbar with a link to go home from any page, like this:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { NavLink } from 'react-router-dom';
import unmountComponentAtNode from 'react-dom';
class NavBar extends Component {
render() {
return (
<div className="navbar">
<NavLink className="link"
to="/"
exact
>Home</NavLink>
</div>
);
}
};
export default NavBar;
If I go to the form, then change my mind and decide I want to go back to the homepage, the url changes when I press the navlink, but the form is still rendered on the homepage. I can keep going back and forth between routes, but the only way to get the form to unmount from the DOM is to refresh the page. What causes this behavior, and what can I do to fix it? I have experienced similar issues before in React but have never found the solution. Thanks!
Edit** I tried adding this to the navlink:
render() {
const refCallback = node => {
unmountComponentAtNode(node)
}
return (
<div className="navbar">
<NavLink className="link"
to="/"
exact
innerRef={refCallback}
>Home</NavLink>
</div>
);
}
};
as per the react router docs, but it gives me this error:
unmountComponentAtNode(...): Target container is not a DOM element.
Here is the code in app.js
import React, { Component } from 'react';
import './App.css';
import { Router, Route } from 'react-router-dom';
import createBrowserHistory from 'history/createBrowserHistory';
import Home from './Components/Home'
import Navbar from './Components/Navbar';
import addHand from './Components/Forms/addHand';
export const history = createBrowserHistory();
class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<h1 className="App-title-top">Hi Adam, welcome to your Personal
Poker Universe!</h1>
<h1 className="App-title-middle">Not Adam? GTFO!</h1>
<h1 className="App-title-bottom">Just Kidding, you can stay</h1>
</header>
<Router history= {history}>
<div>
<Navbar/>
<Route exact path='/' component= {Home} />
</div>
</Router>
</div>
);
}
}
export default App;
Define one Router in your App.js:
<Router history={history}>
<Switch>
<Route exact path="/" component={Home} />} />
<Route path="/hands/new" component={addHand} />
</Switch>
</Router>
then try navigating between routes it should work. Please Let me know if it doesn't work
I have a mini project in which the first page having title homepage but the next page contacts is click through link it retains the homepage as title. I've explicitly declared title as Contact Us but then also it shows Homepage.
Here's my code:
For App.js:
import React, { Component } from 'react';
import {BrowserRouter as Router, Route, Switch, Link} from 'react-router-dom';
import ContactUs from '/Users/yashchoksi/Documents/linking/src/ContactUs';
class App extends Component {
render() {
return (
<Router>
<div>
<title>HomePage</title>
<Link to="/src/ContactUs">Contact Us</Link>
<Switch>
<Route exact path="/src/ContactUs" component={ContactUs}/>
</Switch>
</div>
</Router>
);
}
}
export default App;
And for Contact Us page:
import React, { Component } from 'react';
class ContactUs extends Component {
render(){
return(
<div>
<title>ContactUs</title>
Hello From COntactUs.
</div>
);
}
}
export default ContactUs;
Please see and tell me how to declare title for dynamic naming!
You can set it in your component:
import React, { Component } from 'react';
class ContactUs extends Component {
componentDidMount() {
document.title = 'Contact Us'
}
render(){
return(
<div>
<title>ContactUs</title>
Hello From COntactUs.
</div>
);
}
}
export default ContactUs;
Just use the following code:
componentWillMount(){
document.title="Title name";
}
Edit:
componentWillMount will be deprecated in React 17, so you can use componentDidMount instead.
For better api and server rendering, use react-helmet. It is also a one-liner at its simplest.
I have made 3 components
1)Navbar
2)Content
3)Pagination
On home page I want to display all 3 components.
I have made another component Matchinfo which should get displayed when we click on view stats button (see screenshot for more clarification) .
In app.js how should I make use of Routes so that 3 components will get display on home page i.e localhost:3000/ and when I click on view stats button it should render component Matchinfo.
In app.js :
import React, { Component } from 'react';
import { Route, NavLink, HashRouter } from "react-router-dom";
import './App.css';
import Navbar from './components/navbar';
import Content from './components/content';
import Pagination from './components/pagination';
import Matchinfo from './components/matchinfo';
class App extends Component {
render() {
return (
<div className="App">
<div className="content">
<Route path="/" component={Navbar, Content, Pagination}/>
<Route path="/match" component={Matchinfo}/>
</div>
</div>
);
}
}
export default App;
You no need to call these components in app.js using routes. I would request you to create sepearte component like Home(see example below home.js).
Then, In app.js call Home component
import Home from './components/home';
<Route path="/" component={Home}/>
create home.js under components
Call Navbar, Content annd Pagination components in Home component
import React, {Component} from "react";
import Navbar from './components/navbar';
import Content from './components/content';
import Pagination from './components/pagination';
class Home extends Component {
constructor(props) {
super(props);
this.state = {
}
}
componentWillMount() {
}
render() {
return (
<div>
<Navbar/>
<Content />
<Pagination/>
</div>
)
}
}
export default Home;
Since you want to display Navbar, Content annd Pagination components in home page so do it like above way. Here Home is your parent component and Navbar, Content annd Pagination are child components to Home.
One route is enough mostly for one web page and in React most of times you will play with child components. You no need to configure all the components with routes.
There are several ways achieving the result.
The first one is using render method for home Route. Also, use exact attribute of Route to ensure the location is matched exactly.
import React, { Component } from 'react';
import { Route, NavLink, HashRouter } from "react-router-dom";
import './App.css';
import Navbar from './components/navbar';
import Content from './components/content';
import Pagination from './components/pagination';
import Matchinfo from './components/matchinfo';
class App extends Component {
render() {
return (
<div className="App">
<div className="content">
<Route path="/" render={(props) => (
<React.Fragment>
<Navbar/>
<Content />
<Pagination/>
<React.Fragment/>
)} exact/>
<Route path="/match" component={Matchinfo} exact/>
</div>
</div>
);
}
}
export default App;
The second one, create auxiliary component Home, for example, and include it in your route, like this:
<Route path="/" component={Home} exact/>