Hi I googled everywhere about my problem still no luck for me.
Here i attached my sample code.
import React from 'react';
import {
BrowserRouter,
Route,
Switch,
NavLink,
Redirect
} from "react-router-dom";
const Login = () => <div> Login Content <NavLink to ="/AppHome"> go to App</NavLink> </div>;
const Register = () => <div> Register Content </div>;
const AppHome = () => <div> Welcome to the App </div>;
class Authenticate extends React.Component {
render() {
return (
<>
<div>
<NavLink to={"/Login"}> Login </NavLink>
<NavLink to = {"/Register"} > Register < /NavLink>
</div>
<div>
<Switch >
<Route path={"/"} component={Login} />
<Route path={"/Login"} component={Login}/>
<Route path={"/Register"} component = {Register}/>
</Switch>
</div>
</>
);
}
}
class App extends React.Component {
render() {
return (
<BrowserRouter >
<Switch >
<Route path="/" component={Authenticate}/>
<Route path="/AppHome" component={AppHome}/>
</Switch>
</BrowserRouter>
)
}
}
export default App;
Here, In Localhost:3000 , i set Login Component as default to show. it shows the view but when clicking on the signup link, url only changing not the view. what am i done wrong?
You are trying to nest the routes, but in your case this seems unnecessary.
I would setup my routes like this without nested routing:
import React from "react";
import {
BrowserRouter,
Route,
Switch,
NavLink,
Redirect
} from "react-router-dom";
class App extends React.Component {
render() {
return (
<BrowserRouter>
<Authenticate />
<Switch>
<Route path="/" exact component={Login} />
<Route path="/Login" component={Login} />
<Route path="/Register" component={Register} />
<Route path="/AppHome" component={AppHome} />
</Switch>
</BrowserRouter>
);
}
}
const Login = () => (
<div>
Login Content <NavLink to="/AppHome"> go to App</NavLink>
</div>
);
const Register = () => <div> Register Content </div>;
const AppHome = () => <div> Welcome to the App </div>;
class Authenticate extends React.Component {
render() {
return (
<>
<div>
<NavLink to={"/Login"}> Login </NavLink>
<NavLink to={"/Register"}> Register </NavLink>
</div>
</>
);
}
}
export default App;
Codesandbox
import React from 'react'
import ReactDOM from 'react-dom'
import {HashRouter, Route, Switch, NavLink} from 'react-router-dom'
class App extends React.Component {
render() {
return (
<HashRouter>
<Switch>
<Route path="/Login" component={Login} />
<Route path="/Register" component={Register} />
<Route path="/" component={AppHome} />
</Switch>
</HashRouter>
)
}
}
const Login = () => (
<div>
Login Content <NavLink to="/AppHome"> go to App</NavLink>
</div>
)
const Register = () => <div> Register Content </div>
const AppHome = () => <div> Welcome to the App </div>
export default App
ReactDOM.render(<App />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Can you please check this Codesandbox Once.
Related
I'm trying to have a Home Page and with differents links redirect to the differents pages of my app.
I used <Routes> and <Route> to redirect them but is not working. It stay in blank.
I want to Navebar be the layout here, so I read that it must contain the other Routes inside of it
import React from 'react';
import { Route, Routes } from 'react-router';
import './App.scss';
import Navbar from './components/Navbar/Navbar'
import Home from './components/Home/index'
import Contact from './components/Contact'
const App = () => {
return (
<>
<Routes>
<Route path='/' element={<Navbar/>}>
<Route exact={true} index element={<Home/>}></Route>
<Route exact={true} path='contact' element={<Contact/>}></Route>
</Route>
</Routes>
</>
);
}
export default App;
index.js
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
This is the Navbar (which is the onlyone is showing)
class Navbar extends Component{
state = { clicked: false}
handleClick = () =>{
this.setState({clicked: !this.state.clicked})
}
render(){
return(
<>
<nav className='navbar-items'>
<img alt='mRadio' className='navbar-logo' href="../Home/index" src={require('../../assets/images/mRadio.png')}></img>
<div className='menu-icon' onClick={this.handleClick}>
<i className={this.state.clicked ? 'fas fa-times' : 'fas fa-bars'}></i>
</div>
<ul className={this.state.clicked ? 'nav-menu active' : 'nav-menu'}>
{MenuItems.map((item, index)=>{
return (
<li key={index}>
<a className={item.cName} href={item.url}>{item.title}</a>
</li>
)
})
}
</ul>
</nav>
</>
)
}
}
And this is the Home page:
const Index = () => {
return (
<div className='main'>
<video src={videomRadio} autoPlay loop muted/>
</div>
);
}
And this is a Third page:
const Index = () => {
return (
<div>
<p>CONTACT PAGE</p>
</div>
);
}
If you re using the latest version 6, don't use Switch, now is become Routes, try to change the path like this for example if is nested component:
import { Route, Routes } from 'react-router-dom'; //just in case
//...
const App = () => {
return (
<>
<Routes>
<Route path='/' element={<Navbar/>}>
<Route index element={<Home/>} />
<Route path='contact' element={<Contact/>}/>
</Route>
</Routes>
</>
);
}
export default App;
create a child in home and third page.that gives access to that page directly.
I want to use react-router-dom by React with TypeScript. I have a typescript error in <Router> at Home.jsx.
Error
Home.tsx
Type '{ children: Element[]; }' has no properties in common with type 'IntrinsicAttributes'.TS2559(9)
App.tsx
import React from 'react'
import Home from './pages/Home'
function App() {
return (
<div>
<Home />
</div>
)
}
export default App
Home.tsx
import React from 'react'
import { Button, TitleDesc } from '../components/Index'
import { Link } from 'react-router-dom'
import Router from '../router'
const Home: React.FC = () => {
return (
<>
<Router>
<div>
<div>Hii</div>
<div>
<Link to='/login'><Button color='green'>Login</Button></Link>
<Link to='/register'><Button color='blue'>Register</Button></Link>
</div>
</div>
<TitleDesc title='Hi' desc='Hi' />
</Router>
</>
)
}
export default Home
router.tsx
import * as React from 'react'
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import Login from './pages/Login'
import Register from './pages/Register'
import Home from './pages/Home'
const Router = () => {
return (
<BrowserRouter>
<Switch>
<Route exact path='/' component={Home} />
<Route exact path='/Login' component={Login} />
<Route exact path='/Register' component={Registerl} />
<Route component={() => <h1>204 No Content</h1>} />
</Switch>
</BrowserRouter>
)
}
export default Router
It's because of you don't call {props.children} in the router.tsx. Change it to bellow code will remove the error:
const Router = : React.FunctionComponent (props) => {
return (
<BrowserRouter>
<Switch>
<Route exact path='/' component={Home} />
<Route exact path='/Login' component={Login} />
<Route exact path='/Register' component={Registerl} />
<Route component={() => <h1>204 No Content</h1>} />
{props.children}
</Switch>
</BrowserRouter>
)
}
But logically it doesn't need to do something as you did. Because your Router will handle the routes and you don't need to use it again in the Home. So instead of using Home in App, transform it to use Router in your App. Thus your code can change to this:
App.tsx
function App() {
return (
<div>
<Router/>
</div>
)
}
export default App
Home.tsx
const Home: React.FC = () => {
return (
<>
<div>
<div>Hii</div>
<div>
<Link to='/login'><Button color='green'>Login</Button></Link>
<Link to='/register'><Button color='blue'>Register</Button></Link>
</div>
</div>
<TitleDesc title='Hi' desc='Hi' />
</>
)
}
export default Home
Router.tsx
This component won't change.
I think Router only accepts a single child. You have two: div and TitleDesc. Wrap those in a <> and it should be fine:
const Home: React.FC = () => {
return (
<>
<Router>
<> {/* <-- new wrapper */ }
<div>
<div>Hii</div>
<div>
<Link to='/login'><Button color='green'>Login</Button></Link>
<Link to='/register'><Button color='blue'>Register</Button></Link>
</div>
</div>
<TitleDesc title='Hi' desc='Hi' />
</> {/* <-- new wrapper */}
</Router>
</>
)
}
I am new to React and trying to create a layout with nested routes. Here's my scenario
show Login when URL is /
show Dashboard when URL is /dashboard
show Profile when URL is /dashboard/profile (this should load
inside the dashboard content area)
The login page and dashboard page are loading properly when the URL is accessed in the browser but for /dashboard/profile, the browser goes to a blank page instead of loading it inside the dashboard component.
Index.js
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root'));
App.js
class App extends Component {
render() {
return (
<div>
{/* <Switch> */}
<Route exact path='/' component={SignIn}/>
<Route exact path='/dashboard' component={Dashboard}/>
{/* </Switch> */}
</div>
);
}
}
export default App;
Dashboard.js
class Dashboard extends React.Component {
render() {
const { classes } = this.props;
return (
<React.Fragment>
<CssBaseline />
<div className={classes.root}>
<Header classes={classes} open={this.state.open} click={this.handleDrawerOpen} />
<Sidebar classes={classes} open={this.state.open} click={this.handleDrawerClose} />
<main className={classes.content}>
<div className={classes.appBarSpacer} />
*********I expect profile component to load here
but when I access the URL /dashboard/profile I get a new blank page*********
Route path="/dashboard/profile" exact component={Profile} />
</main>
</div>
</React.Fragment>
);
}
}
You need to remove the exact prop from the Dashboard route (present in Switch) while doing the child routing.
This is the minimal implementation of your use case:
import React, { Component } from "react";
import "./styles.css";
import {
NavLink,
Redirect,
Route,
BrowserRouter as Router,
Switch
} from "react-router-dom";
const App = () => (
<Router>
<div className="App">
<ul>
<li>
<NavLink to="/login">Login</NavLink>
</li>
<li>
<NavLink to="/dashboard">Dashboard</NavLink>
</li>
</ul>
<Switch>
<Route exact path="/login" component={Login} />
<Route path="/dashboard" component={Dashboard} />
</Switch>
</div>
</Router>
);
const Login = () => <span>Login Page</span>;
const Dashboard = () => {
return (
<div>
<div>Dashboard Page</div>
<NavLink to="/dashboard/profile">Go to profile</NavLink>
<div>
<Route exact path="/dashboard/profile" component={Profile} />
</div>
</div>
);
};
const Profile = () => {
return <span>Profile Page</span>;
};
export default App;
You can find the working example here:https://codesandbox.io/s/z3py3672v3
I want to show/hide the navigation bar depending upon logged in status of the user. Once the user is authenticated, I store the access-token in local storage. I have tried to show/hide the navigation bar by checking if access-token exists or not. But it needs a hard refresh.
Please find the header component: /components/app-header.js
const AppHeader = () => (
<Navbar color="light" light expand="md">
<NavbarBrand href="/">TestBrand</NavbarBrand>
<Nav navbar>
<NavItem>
<Link className="lnk" to='/users'>Users</Link>
</NavItem>
</Nav>
<Nav className="ml-auto" navbar>
<NavItem>
<Link className="lnk" to='/logout'>Logout</Link>
</NavItem>
</Nav>
</Navbar>
)
The file which handles all the routes is as below (routes/index.js):
import React from 'react';
import { BrowserRouter, Route, Link, Switch } from 'react-router-dom';
import { AppHeader } from '../components';
export default () => (
<BrowserRouter>
<div>
{
localStorage.getItem('access-token') &&
<div>
<AppHeader />
</div>
}
<Switch>
<Route exact path="/users" component={Users} />
<Route exact path="/users/add" component={Users} />
<Route exact path="/users/:id" component={Users} />
</Switch>
</div>
</BrowserRouter>
)
The main App just contains the following code:
import React, { Component } from 'react';
import Routes from '../routes';
import '../style.css';
class App extends Component {
render() {
return (
<div>
<Routes />
</div>
)
}
}
export default App;
I do not want to refresh the page, as it defeats the very purpose of SPA. How can I achieve that?
Make Routes a stateful Component.
import React from 'react';
import { BrowserRouter, Route, Link, Switch } from 'react-router-dom';
import { AppHeader } from '../components';
class Routes {
this.state = {loggedIn: false}
componentDidMount() {
if(localStorage.getItem('access-token')) {
this.setState({loggedIn: true})
}
//attach an event listener to the window object for storage event.
$(window).on('storage',() => {
if(localStorage.getItem('access-token')) {
this.setState({loggedIn: true})
}
});
}
render() {
return (
<BrowserRouter>
<div>
{
this.state.loggedIn &&
<div>
<AppHeader />
</div>
}
<Switch>
<Route exact path="/users" component={Users} />
<Route exact path="/users/add" component={Users} />
<Route exact path="/users/:id" component={Users} />
</Switch>
</div>
</BrowserRouter>)
}
}
export default Routes;
After the component is mounted you are listening to localStorage updates. if local storage is changed it will update the state of the component as required.
I have a single page React app. I have a BaseLayout component which serves as the container for the app. BaseLayout displays the header and footer and also the content as shown below:
class App extends Component {
render() {
return (
<div>
<BaseLayout>
</BaseLayout>
</div>
);
}
}
BaseLayout
export default class BaseLayout extends Component {
render() {
return (
<div>
<NavBar />
{this.props.children}
<Footer />
</div>
)
}
}
index.js
ReactDOM.render(
<BrowserRouter>
<Switch>
<Route path="/page_one" component={PageOne} />
<Route path="/page_two" component={PageTwo} />
<Route path="/" component={App} />
</Switch>
</BrowserRouter>,
document.getElementById('root')
)
All the navigation is inside the navBar.js component.
navBar.js
export default class NavBar extends Component {
render() {
return (
<div className="nav-bar">
<button><Link to="/">Home</Link></button>
<button><Link to="/page_one">Page One</Link></button>
<button><Link to="/page_two">Page Two</Link></button>
</div>
)
}
}
pageOne.js and pageTwo.js
export default class PageOne extends Component {
constructor(props) {
super(props)
}
render() {
return (
<div>
<h1>Page One </h1>
</div>
);
}
}
The problem is that when I go to page_one or page_two URL it only shows the content of the component and not the navigation bar.
How can I make the navigation bar and footer visible on all the pages using react router and react framework?
UPDATE:
App.js
class App extends Component {
render() {
return (
<div>
<BaseLayout>
</BaseLayout>
</div>
);
}
}
export default App;
I changed my index.js to the following:
ReactDOM.render(
<BrowserRouter>
<Route path="/" component={App}>
<Switch>
<Route path="/page_one" component={PageOne} />
<Route path="/page_two" component={PageTwo} />
</Switch>
</Route>
</BrowserRouter>,
document.getElementById('root')
)
Now, I get the following:
And the page does not go anywhere if I use the above code:
I think you should "lift" the App as the root Route.
By the way, Is App the same as BaseLayout? hard to tell from your example.
Example:
const Index = () => {
return (
<BrowserRouter>
<div>
<Route component={App} />
<Switch>
<Route path="/page_one" component={PageOne} />
<Route path="/page_two" component={PageTwo} />
</Switch>
</div>
</BrowserRouter>
);
};
A running code example, i'm not using a stack snippet as i can't use react-route with push state here.
I'm posting the entire code in case the url will be broken in the future:
import React from "react";
import { render } from "react-dom";
import { BrowserRouter, Route, Link, Switch } from "react-router-dom";
const Footer = () => <div>Footer...</div>;
class BaseLayout extends React.Component {
render() {
return (
<div>
<NavBar />
{this.props.children}
<hr/>
<Footer />
</div>
);
}
}
class NavBar extends React.Component {
render() {
return (
<div className="nav-bar">
<button>
<Link to="/">Home</Link>
</button>
<button>
<Link to="/page_one">Page One</Link>
</button>
<button>
<Link to="/page_two">Page Two</Link>
</button>
</div>
);
}
}
const PageOne = () => <h1>Page One</h1>;
const PageTwo = () => <h1>Page Two</h1>;
class App extends React.Component {
render() {
return (
<div>
<BaseLayout>{this.props.children}</BaseLayout>
</div>
);
}
}
const Index = () => {
return (
<BrowserRouter>
<div>
<Route component={App} />
<Switch>
<Route path="/page_one" component={PageOne} />
<Route path="/page_two" component={PageTwo} />
</Switch>
</div>
</BrowserRouter>
);
};
render(<Index />, document.getElementById("root"));