React Router v4 not displaying components - reactjs

The component is not been displayed when I navigate to localhost:3000/signup
Is it because react router is updated to v4 and they way you route in react has now changed?
I have my main.js file
import Signup from '../imports/ui/Signup';
import
const routes = (
<Router history={browserHistory}>
<Route path="/signup" component={Signup}/>
</Router>
);
Signup component
import React from 'react';
export default class Signup extends React.Component {
render() {
return <p>Signup</p>
}
}
I'm using react router v4, also using Meteor.

React Router v4 is a re-write of React Router so you'll have to read the new API and adjust your code accordingly. I suggest going through all the examples which can be found here. Here's the basic example that looks similar to your code. The biggest thing you'll notice is you no longer have a centralized route config. Instead, you render `` s dynamically when you need them.
import React from 'react'
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom'
const BasicExample = () => (
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/topics">Topics</Link></li>
</ul>
<hr/>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route path="/topics" component={Topics}/>
</div>
</Router>
)
const Home = () => (
<div>
<h2>Home</h2>
</div>
)
const About = () => (
<div>
<h2>About</h2>
</div>
)
const Topics = ({ match }) => (
<div>
<h2>Topics</h2>
<ul>
<li>
<Link to={`${match.url}/rendering`}>
Rendering with React
</Link>
</li>
<li>
<Link to={`${match.url}/components`}>
Components
</Link>
</li>
<li>
<Link to={`${match.url}/props-v-state`}>
Props v. State
</Link>
</li>
</ul>
<Route path={`${match.url}/:topicId`} component={Topic}/>
<Route exact path={match.url} render={() => (
<h3>Please select a topic.</h3>
)}/>
</div>
)
const Topic = ({ match }) => (
<div>
<h3>{match.params.topicId}</h3>
</div>
)
export default BasicExample

Related

Link not re-directing to a page in React

I am trying to make a Navbar but the isn't re-directing to the given page. If I click any of the links in the Navbar, it would change the path in the url bar but won't re-direct to that page. I am not sure if I am missing anything. When I replace it with the tags, it works perfectly.
Navbar.js
import React from "react";
import { BrowserRouter as Router, Link, Switch } from "react-router-dom";
const Navbar = () => {
return (
<Router>
<Switch>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/articles">Articles</Link>
</li>
<li>
<Link to="/articles-all">All articles</Link>
</li>
</ul>
</nav>
</Switch>
</Router>
);
};
export default Navbar;
App.js
import React from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
import './App.css'
//pages
import Home from "./Pages/Home";
import About from "./Pages/About";
import Articles from "./Pages/Articles";
import ArticlesList from "./Pages/ArticlesList";
//components
import Navbar from './components/Navbar';
const App = () => {
return (
<div>
<Navbar/>
<Navigation />
</div>
);
};
export default App;
const Navigation = () => {
return (
<Router>
<div id="page-body">
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/articles" component={Articles} />
<Route path="/articles-all" component={ArticlesList} />
</div>
</Router>
);
};
Since you define the Router within Navigation and another one in Navbar your Links are not able to communicate to the Router Component in Navigation as they just communicate to their nearest parent Router component
You must you use a single Router instance to be able to perform seemless navigation within your App. Also a Switch component is not needed with Links but with Route
const App = () => {
return (
<Router>
<Router component={Navbar}/> // rendered as default route so that they receive router props
<Router component={Navigation} />
</Router>
);
};
export default App;
const Navigation = () => {
return (
<div id="page-body">
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/articles" component={Articles} />
<Route path="/articles-all" component={ArticlesList} />
</div>
);
};
const Navbar = () => {
return (
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/articles">Articles</Link>
</li>
<li>
<Link to="/articles-all">All articles</Link>
</li>
</ul>
</nav>
);
};
export default Navbar;
Here's a working codesandbox URL https://codesandbox.io/s/frosty-black-3i8hp?file=/src/App.js
You were wrapping links with browserRouter and Switch. These APIs are intended to wrap Routes only.
So, It wasn't able to communicate well with your react app.

React Router 5.1 - useLocation hook - determine past locations

According to React Router 5.1 documentation it should be possible to see "where the app is now, where you want it to go, or even where it was". In my app I need to see "where it was" - what locations I have visited before landing at a specific location.
More precisely; I wish to find a prevoious location matching a certain pattern. That location might be two or three locations ago.
However - I cannot figure out how to perform this.
What is the best and recommended approach to achieve this?
Kind regards /K
I turns out the best way, for me, to see where the application has been been is to simply use the state property in the React Router Link.
This article on how to pass state from Link to components really helped explain how to use the Link state.
Basically the Link can pass the state property to the rendered component.
<Link to={{ pathname: "/courses", state: { fromDashboard: true } }} />
The rendered component then access the state via props.location.state
This in conjunction with passing props to components generating the links solved my problem! (^__^)
In React Router you can use the goBack() method if you need to react a previous path in your history. Also, there is a possibility to push your path to history state, but that’s only needed if you need to know the URL of the previous location.
You can read more about this functionality from here: https://reacttraining.com/react-router/web/api/history
You can check this example. Hope it helps you.
import React from "react";
import {BrowserRouter as Router,Switch,Route,Link} from "react-router-dom";
import { withRouter } from "react-router";
export default function BasicExample() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
<hr />
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
return (
<div>
<h2>Home</h2>
</div>
);
}
const About = withRouter(({history, ...props}) => (
<h1 {...props}>
About
<hr/>
<button onClick={() => {history.push('/')}}>go back</button>
</h1>
));
Another Example for going back -2
import React from "react";
import {BrowserRouter as Router, Switch, Route, Link} from "react-router-dom";
import {withRouter} from "react-router";
export default function BasicExample() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/about/insideabout">Inside About</Link>
</li>
</ul>
<hr/>
<Switch>
<Route exact path="/">
<Home/>
</Route>
<Route exact path="/about">
<About/>
</Route>
<Route path="/about/insideabout">
<InsideAbout/>
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
return (
<div>
<h2>Home</h2>
</div>
);
}
const About = withRouter(({history, ...props}) => (
<div>
<h1>
About
<hr/>
<button onClick={() => {
// history.push('/')
history.goBack(-1);
}}>go back
</button>
</h1>
</div>
));
const InsideAbout = withRouter(({history, ...props}) => (
<h1 {...props}>
Inside About
<hr/>
<button onClick={() => {
history.goBack();
}}>go back
</button>
<button onClick={() => {
history.go(-2);
}}>go home
</button>
</h1>
));

Login page in react using react hooks

I tried to do sample login page in react using react hooks(useState()).
When user is not login I redirect it to home. When I use hooks, that is not being redirected.
here is my code
import React, {useState} from 'react';
import {BrowserRouter as Router, Route, NavLink, Redirect} from 'react-router-dom';
import './App.css';
function App() {
const [isLogin, changeLogin] = useState(false);
return (
<Router>
<div>
<ul>
<li>
<NavLink to="/" exact activeStyle={{'color':'green'}}>Home</NavLink>
</li>
<li>
<NavLink to="/about" activeStyle={{'color':'green'}}>About</NavLink>
</li>
<li>
<NavLink to="/user/stack" activeStyle={{'color':'green'}}>User Stack</NavLink>
</li>
<li>
<NavLink to="/user/overflow" activeStyle={{'color':'green'}}>User Overflow</NavLink>
</li>
</ul>
<input className="loginButton" type="button" value={isLogin ? 'Logout' : 'Login'} onClick={ () => changeLogin(!isLogin)}/>
<hr/>
<Route path="/" exact strict render={() => <Home/>} />
<Route path="/about" exact strict render={() => <About/>} />
<Route path="/user/:username" exact strict render={({match}) => {
return(isLogin ? (<User username={match.params.username}/>) : (<Redirect to="/" />))
}} component={User} />
</div>
</Router>
);
}
function Home(){
return(
<div>
<h2>Home</h2>
</div>
)
}
function About(){
return(
<div>
<h2>About</h2>
</div>
)
}
const User = ({match}) => {
return(<h2>Welcome User {match.params.username}</h2>);
}
export default App;
I use usestate to handle the state which tells the user is logged in or not. How can I achieve this using react hooks?
Removing component={User} on your route should solve the problem :
<Route path="/user/:username" exact strict
render={({match}) => isLogin ?
<User username={match.params.username}/> :
<Redirect to="/" />
}
/>

React Router isn't working properly

I upgraded from react Router v2 to v4 and then everything was broken! I searched on google with errors and learned a thing that is latest version of react router is totally re-written. I tried to follow the docs for updating my app. However I copied codes from official docs and it is working perfectly But when I'm working with my components and structure it's not routing. I couldn't figure out the actual problem. everything seems OK but still it's not routing.
Update
I did figure out the problem. it was with rendering the component from Route. I was using Component in my code but it should be component that's why my code wasn't working. It didn't event throw an error !
This code below is working for routing
import React from 'react';
import { render } from 'react-dom';
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom';
const About = () => (
<div>About page</div>
)
const Home = () => (
<div>Home component</div>
)
const AppComponent = () => (
<div>App component is rendered as well</div>
)
render(
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/contact">Contact</Link></li>
</ul>
<hr/>
<Route exact path="/" component={Home}/>
<Route exact path="/" component={AppComponent}/>
<Route path="/about" component={About}/>
</div>
</Router>,
document.querySelector('#app')
)
This code below isn't working for routes
import React from 'react';
import { render } from 'react-dom';
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom';
const SignUp = () => (
<div>This is Sign up Page</div>
)
const Home = () => (
<div>Home component</div>
)
const AppComponent = () => (
<div>App component is rendered as well</div>
)
render(
<Router>
<div className="container">
<nav className="navbar navbar-default">
<div className="container-fluid">
<div className="navbar-header">
<Link to="/" className="navbar-brand">Red Dice</Link>
</div>
<div className="collapse navbar-collapse">
<ul className="nav navbar-nav navbar-right">
<li><Link to="/signup">Sign up</Link></li>
</ul>
</div>
</div>
</nav>
<Route exact path="/" Component={Home} />
<Route exact path="/" Component={AppComponent} />
<Route path="/signup" Component={SignUp} />
</div>
</Router>,
document.querySelector('#app')
)
I have another question about browserHistory. In older version we had that but in newer version react router doesn't provide this. So what can I use in newer version to work with browserHistory?
In the newest version, you must use BrowserRouter to replace browserHistory option:
import { BrowserRouter } from 'react-router-dom'
<BrowserRouter>
<div> ... </div>
<Route />
<Route />
</BrowserRouter>
You can read more about this in https://reacttraining.com/web/api/BrowserRouter

How to get withRouter to pass match params to component?

I want to access the match params on the navigation on my app, I'm using react and react-router-dom. Here is a code snipped for simple example I made, as you can see on the Topics component I get the correct match at component level but not in the nav bar, I do get the correct url path in the location prop so I'm not sure if I'm doing this right.
This would be the working snippet, since I couldn't add react-router-dom to the stack overflow snippet.
import { BrowserRouter as Router, Route, Link, withRouter } from "react-router-dom";
const BasicExample = (props) =>
<Router>
<div>
<Nav/>
<hr />
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/topics" component={Topics} />
</div>
</Router>;
const About = () => (
<div>
<h2>About</h2>
</div>
);
const Home = () => (
<div>
<h2>Home</h2>
</div>
);
const Navigation = (props) => (
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
<li>{`match prop -> ${JSON.stringify(props.match)}`}</li>
<li>{`location prop -> ${JSON.stringify(props.location)}`}</li>
</ul>
);
const Nav = withRouter(Navigation);
const Topic = ({ match, location }) => (
<div>
<h3>{match.params.topicId}</h3>
<li>{`match prop -> ${JSON.stringify(match)}`}</li>
<li>{`location prop -> ${JSON.stringify(location)}`}</li>
</div>
);
const Topics = ({ match, location, history }) => (
<div>
<h2>Topics</h2>
<li>{`match prop -> ${JSON.stringify(match)}`}</li>
<li>{`location prop -> ${JSON.stringify(location)}`}</li>
<ul>
<li>
<Link to={`${match.url}/rendering`}>
Rendering with React
</Link>
</li>
<li>
<Link to={`${match.url}/components`}>
Components
</Link>
</li>
<li>
<Link to={`${match.url}/props-v-state`}>
Props v. State
</Link>
</li>
</ul>
<Route path={`${match.url}/:topicId`} component={Topic} />
<Route
exact
path={match.url}
render={() => <h3>Please select a topic.</h3>}
/>
</div>
);
ReactDOM.render(<BasicExample />, document.getElementById("root"));
<body>
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
</body>
For detecting :topicId in <Nav> use matchPath imported from react-router:
import { matchPath } from 'react-router'
matchPath(location.pathname, {
path:'/topics/:topicId',
exact: true,
strict: false
}})
This is a little outdated now. Can be achieved with react-router-dom by simply doing something like:
import { withRouter } from 'react-router-dom';
console.log(props.match.params);
Don't forget to wrap the component inside withRouter
export default withRouter(YourComponent);
props.match.params will return an object with all the params.

Resources