I want to open FormStatus in a new page when I click a button in Form page.
Below is my code.
App.js:
import Form from "./components/Form";
import FormStatus from "./components/FormStatus";
import { BrowserRouter as Router, Route } from "react-router-dom";
function App() {
return (
<Router>
<div className="App">
<Route path="/" component={Form}/>
<Route exact path="/form-status" component={FormStatus}/>
</div>
</Router>
);
}
export default App;
Form.js
import { Link } from "react-router-dom";
const Form = () => {
return (
<div>
<h1>Form Page</h1>
<Link to="/form-status"><button>click</button></Link>
</div>
);
}
export default Form;
FormStatus.js:
import React, {Component} from "react";
class FormStatus extends Component {
render(){
return(
<h1>Form Status Page</h1>
)
}
}
export default FormStatus;
when I click on the button on Form component, my url changes to http://localhost:3000/form-status,
but instead of opening a new page, my FormStatus component comes below Form component.
I want FormStatus to open new a page and only shows contents of my FormStatus component and not contents of Form component
Well, to make this work, you need to change two things in your current code.
Use the Switch from the react-router-dom and wrap your routes within it.
Make your home page (/) route exact instead of the /form-status route, because the /form-status route also includes the leading slash (/). So since both of them will match the expected route it will render them together.
So your code should be something like this in the App.js:
import React from "react";
import Form from "./components/Form";
import FormStatus from "./components/FormStatus";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
export default function App() {
return (
<Router>
<Switch>
<div className="App">
<Route exact path="/" component={Form} />
<Route path="/form-status" component={FormStatus} />
</div>
</Switch>
</Router>
);
}
Working Demo:
Related
I am a bit lost with this issue for a whole day.
On button click the url changes but does not render the new page and I don't understand why.
I am using react-dom-router 5.2.0
INDEX JS
import {Router} from 'react-router-dom';
import history from './history';
ReactDOM.render(
<React.StrictMode>
<Router history={history}>
<App />
</Router>
</React.StrictMode>,
document.getElementById('root')
);
APP JS
import Server from './Server';
import React from 'react';
function App() {
return (
<Server />
);
}
export default App;
SERVER JS
export default class Server extends Component
{
render()
{
return(
<div className="Homepage" >
<h1 className="header">Server</h1>
<button className="button"
onClick={() => history.push('/control')}>
Lets go
</button>
}
</div>
);
}
}
Please Note : I added <Control/> directly in the render method above and it renders the component all well .
CONTROL JS
import React, {Component} from 'react';
import Page2_View from './Page2_View';
export default class Control extends Component
{
constructor(props)
{
super(props);
}
render()
{
return(
<Page2_View/>
);
}
}
Page2_View
import React, {Component} from 'react';
const Page2_View = (props) =>
{
return(
<h1> PAGE 2 VIEW </h1>
);
}
export default Page2_View;
ROUTES JS
import {BrowserRouter as Router, Route, Redirect, Switch} from 'react-router-dom';
const Routes = () =>
{
return(
<Router>
<div>
<Switch>
<Route exact path="/test" component={Server}/>
<Redirect from = '/test' to = '/control'/>
<Route exact path="/control" component={Control}/>
</Switch>
</div>
</Router>
);
}
export default Routes;
HISTORY JS
import {createBrowserHistory as history} from 'history';
export default history();
I appreciate all the help. Thank you
I think the problem is that react-router-dom is not aware of this history.push('/control') you're doing; i.e. if you want to redirect to another route, it should be through react-router, not outside of it.
You have a few options:
Use the useHistory hook: https://reacttraining.com/react-router/web/api/Hooks/usehistory
Your button could be wrapped in a Link component: https://reacttraining.com/react-router/web/api/Link
Get the router through props with the withRouter component, as explained in: Programmatically navigate using react router V4.
I have realized what I was doing wrong and was able to solve my issue.
The key was to understand that the Router module from react-router-dom
comes with three props : path , history, and component.
So in order to redirect a page on button click all I had to do embed all my Routes between tag in the App.js
APP JS
function App() {
return (
<Router>
<Switch>
<Route exact path="/test" component={componentA}/>
<Route exact path="/test2" component={componentB}/>
</Switch>
</Router>
);
}
export default App;
And then you can use button onClick to redirect
COMPONENTA JS
<button variant="secondary"
className="button" size="lg"
onClick={() => this.props.history.push('/test2')}>
RedirectTo
</button>
Hope this will be helpful to others who come across this!
In server.js file instead of button use navlink or link from reactrouter below is a saple code
<NavLink to="/control">control</NavLink>
Import every component to routing component then use router switch and redirect statements like below
import Main from './component/Main'
import Welcome from "./component/welcome"
import { Route, BrowserRouter as Router, Switch,Redirect } from 'react-router-dom'
function App() {
return (
<Router>
<Switch>
<Redirect from="/" to="/home" exact />
<Route exact path="/home" component={Main} />
<Route path="/welcome" component={Welcome} />
</Switch>
</Router>
);}
export default App;
and in your component where you re clicking import link or nav link i prefer using navlink
and use it to redirect to page on click
import { NavLink } from 'react-router-dom'
<NavLink to="/home">home</NavLink>
After several attempts, I have managed to implement basic nested-routing with React-router-dom.
Here's the simple project structure:
Here are the relevant files:
App.js
import React from "react";
import logo from "./logo.svg";
import "./App.css";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import ParentComponent from "./Components/nestedComponents/ParentComponent";
import NavBar from "./Components/Shared/NavBar";
function App() {
return (
<div className="App">
<BrowserRouter>
<NavBar />
<Switch>
<Route path="/home" name="Home" component={ParentComponent} />
</Switch>
</BrowserRouter>
</div>
);
}
export default App;
NavBar.js
import React from "react";
import { Link } from "react-router-dom";
export default function NavBar() {
return (
<div>
<Link to={`home/nestedComponentOne`}> Nested Component One </Link>
<Link to={`home/nestedComponentTwo`}> Nested Component Two </Link>
</div>
);
}
ParentComponent.js
import React from "react";
import nestedComponentOne from "./nestedComponentOne";
import nestedComponentTwo from "./nestedComponentTwo";
import { Switch, Route } from "react-router-dom";
export default function ParentComponent() {
return (
<div>
<Switch>
<Route path="/home/nestedComponentOne" component={nestedComponentOne} />
<Route path="/home/nestedComponentTwo" component={nestedComponentTwo} />
</Switch>
</div>
);
}
nestedComponentOne.js
import React from "react";
export default function nestedComponentOne() {
return <div>NESTED COMPONENT 1</div>;
}
nestedComponentTwo.js
import React from "react";
export default function nestedComponentTwo() {
return <div>NESTED COMPONENT 2</div>;
}
So here's the Result:
If I click on nestedComponentOne:
If I click on nestedComponentTwo:
The problem is when I click again on nestedComponentOne (or Two) after the I have clicked it the first time, the route gets added to the url string instead of replacing it:
Some update need for your code.
Working Demo
NavBar.js
Here you forget to add slash / at front to link from root.
<Link to={`/home/nestedComponentOne`}> Nested Component One </Link>
<Link to={`/home/nestedComponentTwo`}> Nested Component Two </Link>
ParentComponent.js
As we removed the Switch from this component, so we need to get the matching information from parent router and pass the path to navigate the corresponding your nested component
export default function ParentComponent({ match }) {
return (
<div>
<Route path={`${match.path}/nestedComponentOne`} component={nestedComponentOne} />
<Route path={`${match.path}/nestedComponentTwo`} component={nestedComponentTwo} />
</div>
);
}
Why don't you try putting all the route in one file. Something like this:
<Route exact path="/home" name="Home" component={ParentComponent} />
<Route path="/home/nestedComponentOne" component={nestedComponentOne} />
<Route path="/home/nestedComponentTwo" component={nestedComponentTwo} />
I have this code I have been trying to get to work. Cannot figure out whats wrong with it! There are no errors and I have tried several ways of importing/exporting, and changing the functions to const.
import React, { Component } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import { Home } from "./Home";
import { Contact } from "./Contact";
class App extends Component {
render() {
return (
<React.Fragment>
<Router>
<Switch>
<Route path="/" component={Home} />
<Route path="/contact">
<Contact />
</Route>
</Switch>
</Router>
</React.Fragment>
);
}
}
export default App;
Then I have two separate functions
import React from "react";
export function Home() {
return (
<div>
<h2>Whats up!</h2>
<p>This is sample text. </p>
</div>
);
}
import React from "react";
export function Contact() {
return (
<div>
<h2>Contact page!</h2>
<p>This is different text. </p>
</div>
);
}
export default Contact;
Based on your last comment - "The above code actually displays whatever is in the first Route no matter the url", the issue is that you're not providing the Route components with an exact prop of true.
Switch will render the first matching Route and skip all the other ones. Since / "matches" all routes, you're only seeing the Home component.
How to redirect from one class component to another class component/fresh page in ReactJS.
Currently, I am able to load new components through the link tags in react-router.
but then I want to redirect to another class component just like href in HTML to another fresh page where the previous states will not be available and it's a fresh new class.
Example:- I have 3 Pages
LandingPage
LoginPage
SignupPage
Initially, LandingPage will be opened and after that when I click the respective screen it will open.
How can i load a fresh LoginPage & SignupPage from LandingPage. Both SignupPage and LandingPage have a separate class component to manage the state of that particular screens.
Please share some code references.
Thanks in advance.. :)
If you want to open login or signup page from landing page you can simply call history.push('/login') from landing page component to open login page. history is available in every route so can be called directly.
index.js
import { BrowserRouter, Route,Switch} from 'react-router-dom';
import landingPage from './landingPage';
import login from './login';
import signup from './signup';
render(){
<BrowserRouter>
<Switch>
<Route exact={true} path="/" component={landingPage} />
<Route exact={true} path="/login" component={login} />
<Route exact={true} path="/signup" component={signup} />
</Switch>
</BrowserRouter>
}
//landing page component
landingPage =()=>{
const openLoginPage= () => {
history.push('/login'); //this will open login page on click of login button
}
return(<div>
< button onClick={openLoginPage}>login</button >
</div>)
}
Will it help to reach your idea? I just share you the idea of routing in react using react-router-dom
App.js
import React, { Component } from "react";
import { BrowserRouter as Router, Route, Switch, Link } from "react-router-dom";
import SignUp from "./signUp";
import Login from "./login";
import Landing from "./landing";
class App extends Component {
render() {
return (
<Router>
<div id="container">
<div>
<Link to="/">Landing</Link>
<Link to="/signup">Sign Up</Link>
<Link to="/login">Login</Link>
</div>
<Switch>
<Route exact path="/signup" component={SignUp} />
<Route exact path="/login" component={Login} />
<Route exact path="/" component={Landing} />
</Switch>
</div>
</Router>
);
}
}
export default App;
You have supposedly created your functional component/ class component, you may import and use accordingly
Update for the class components
Once the routed from one component to another component each component will load with its own state and props
I have put here my class components, you have to make sure all App.js, landing.jsx, signUp.jsx and login.jsx are on the same folder location
landing.jsx
import React, { Component } from "react";
class Landing extends Component {
state={}
render() {
return (
<div>
<h1>Landing page</h1>
</div>
);
}
}
export default Landing;
signUp.jsx
import React, { Component } from "react";
class SignUp extends Component {
state={}
render() {
return (
<div>
<h1>Sign Up page</h1>
</div>
);
}
}
export default SignUp;
login.jsx
import React, { Component } from "react";
class Login extends Component {
state={}
render() {
return (
<div>
<h1>Login page</h1>
</div>
);
}
}
export default Login;
Another way is use push method on button click inside class components, and in both cases route should be there
<button onClick={()=> this.props.history.push('/')} ></button>
or
<button onClick={()=> this.props.history.push('/signup')} ></button>
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/>