Im at my whits end, ive followed tutorials for hours now and i cant get it to work. basically the Switch does not work when i press the links.It just displays nothing but does change the link.
App.js
import './index.css';
import React, { Component } from 'react';
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import Home from './Home';
import Shop from './Shop';
import MainNav from './MainNav';
class App extends Component {
render() {
return (
<BrowserRouter>
<div className="App">
<MainNav />
<Switch>
<Route exact path="/" Component={Home}/>
<Route path="/Shop" Component={Shop}/>
</Switch>
</div>
</BrowserRouter>
);
}
}
export default App;
MainNav.js
import { IoIosHome } from "react-icons/io";
import { IoIosListBox } from "react-icons/io";
import { IoIosBeer } from "react-icons/io";
import { IoIosArrowDown } from "react-icons/io";
import React, { useState, useEffect, useRef, Component, } from 'react';
import { CSSTransition } from 'react-transition-group';
import {NavLink} from "react-router-dom";
class MainNav extends Component {
render() {
return (
<Navbar>
<NavLink exact to="/" ><NavItem icon={<IoIosHome />}/></NavLink>
<NavLink to="/Shop"><NavItem icon={<IoIosBasket />}/></NavLink>
<NavItem icon={<IoIosListBox />} />
<NavItem icon={<IoIosArrowDown />}>
<DropdownMenu></DropdownMenu>
</NavItem>
</Navbar>
);
}
}
function NavItem(props) {
const[open, setOpen] = useState(false);
return (
<li classname="nav-item">
<a href="#" className="icon-button" onClick={() => setOpen(!open)}>
{props.icon}
</a>
{open && props.children}
</li>
);
}
The home and shop just has some text in and works when i bring them in outside the switch. ive tried all these examples changing to classes and functions respectively.
https://www.w3jar.com/react-navigation-example-with-react-router-dom/
https://codesandbox.io/s/xkj1xKO6r?file=/index.js
https://www.youtube.com/watch?v=lCbcB9AU-98&list=PL3I69UeHTyDNUK8t-GIkwWfY73rEW8LS2&index=4&t=0s
Im starting to think im missing something else.
<Route path="/Shop" Component={Shop}/>
to
<Route path="/Shop"><Shop /></Route>
Not sure why it cant read it in curly brackets but this works.
Related
There is a problem using routes in KnowledgeBase.js (code below). I'm trying to write them "inside" another Route (which is in App.js), but nothing works. Perhaps someone can find the problem.
p.s. the console does not give any errors
App.js
import React from "react";
import './App.css';
import Header from "./Components/Header/Header";
import Main from "./Components/Main/Main";
import {Route, Routes} from "react-router-dom";
import Home from "./Components/Main/Home/Home";
import Nav from "./Components/Nav/Nav";
import KnowledgeBase from "./Components/Main/KnowlegeBase/KnowledgeBase";
import Messages from "./Components/Main/Messages/Messages";
function App(props) {
return (
<div className="App">
<Header forHeader={props.state}/>
<Nav forNav={props.state}/>
<Main forMain={props.state}>
<Routes>
<Route path='/home' element={<Home forHome={props.state}/>}/>
<Route path='social-network/' element={<Home forHome={props.state}/>}/>
<Route path='/knowledge-base/*' element={<KnowledgeBase forKnowledgeBase={props.state}/>}/>
<Route path={"/messages"} element={<Messages forMessages={props.state}/>}/>
</Routes>
</Main>
</div>
);
}
export default App;
KnowledgeBase.js
import React from "react";
import style from './KnowledgeBase.module.css';
import Menu from "./Menu/Menu";
import Blocks3 from "./Blocks3/Blocks3";
import {Route, Routes} from "react-router-dom";
import BaseAll from "./BaseAll/BaseAll";
import Blocks2 from "./Blocks2/Blocks2";
import Blocks1 from "./Blocks1/Blocks1";
const KnowledgeBase = (props) => {
return (
<div className={style.knowledgeBase}>
<Menu forMenu={props.forKnowledgeBase}/>
<BaseAll forBaseAll={props.forKnowledgeBase}>
<Routes>
<Route path="/knowledge-base/purchase-and-refund" element={<Blocks3/>}/>
<Route path="/knowledge-base/popular-questions" element={<Blocks2/>}/>
<Route path="/knowledge-base/analytics" element={<Blocks1/>}/>
</Routes>
</BaseAll>
</div>
)
}
export default KnowledgeBase
BaseAll.js
import React from "react";
import style from './BaseAll.module.css'
const BaseAll = (props) => {
return (
<div className={style.baseAll}>
{props.children}
</div>
)
}
export default BaseAll
Menu.js (it has all NavLink)
import React from "react";
import style from './Menu.module.css'
import {NavLink} from "react-router-dom";
const Menu = (props) => {
return (
<div className={style.menu}>
<header>{props.forMenu.menu.header}</header>
<form action="">
<div>
<img src={props.forMenu.menu.search_img} alt=""/>
<input type="text" placeholder={props.forMenu.menu.input}/>
</div>
<button type={"submit"}>{props.forMenu.menu.search_btn}</button>
</form>
<nav>
<NavLink to={"/knowledge-base/analytics"} className={style.menu_NavLink}>{props.forMenu.menu.nav1}</NavLink>
<NavLink to={"/knowledge-base/popular-questions"} className={style.menu_NavLink}>{props.forMenu.menu.nav2}</NavLink>
<NavLink to={"/knowledge-base/purchase-and-refund"} className={style.menu_NavLink}>{props.forMenu.menu.nav3}</NavLink>
</nav>
</div>
)
}
export default Menu
I expect the relevant blocks to appear under the search menu when navigating through NavLink. I tried to implement many options in App.js and KnowledgeBase.js but couldn't find one that would work
In KnowledgeBase.js file, remove /knowledge-base from each route.
React router automatically adds the parent route path with each child. You do not have to write the parent path with each child if it's already placed inside with another route i.e. /knowledge-base/*
const KnowledgeBase = (props) => {
return (
<div className={style.knowledgeBase}>
<Menu forMenu={props.forKnowledgeBase}/>
<BaseAll forBaseAll={props.forKnowledgeBase}>
<Routes>
<Route path="/purchase-and-refund" element={<Blocks3/>}/>
<Route path="/popular-questions" element={<Blocks2/>}/>
<Route path="/analytics" element={<Blocks1/>}/>
</Routes>
</BaseAll>
</div>
)
}
Nav link of react-route-dom changes the route of the Url but doesn't render the component. But if we reload that route, it works.
Navbar code
import React from "react";
import { connect } from "react-redux";
import compose from "compose";
import { Link, NavLink, BrowserRouter, withRouter } from "react-router-dom";
const NavBar = ({ currentUser: user }) => {
if (user) {
for (var a in user) {
if (a === "user") {
user = user[a];
}
}
}
return (
<nav className="navbar navbar-expand-lg navbar-dark bg-primary">
<BrowserRouter>
<Link className="navbar-brand" to="/">
Users UI
</Link>
<button
className="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbarNavAltMarkup"
aria-controls="navbarNavAltMarkup"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon" />
</button>
<div className="collapse navbar-collapse" id="navbarNavAltMarkup">
<div className="navbar-nav" style={{ cursor: "pointer" }}>
{user && (
<React.Fragment>
<a className="nav-item nav-link" href={`/user/${user._id}`}>
{"Edit Profile Mr." + user.name}
</a>
<a className="nav-item nav-link" href="/logout">
Logout
</a>
</React.Fragment>
)}
</div>
</div>
</BrowserRouter>
</nav>
);
};
const mapStateToProps = state => ({
currentUser: state.user.currentUser
});
app.js code
import React, { Component } from "react";
import { Switch, Route, Redirect, } from "react-router-dom";
import { connect } from "react-redux";
import auth from "./services/authService";
import ProtectedRoute from "./components/common/protectedRoute";
import NavBar from "./components/navBar";
import NotFound from "./components/notFound";
import LoginForm from "./components/login";
import Logout from "./components/logout";
import AddUser from "./components/addUser";
import User from "./components/user";
import { setCurrentUser } from "./Redux/user/user-action";
import "./App.css";
class App extends Component {
state = {};
componentDidMount() {
const { setCurrentUser } = this.props;
const user = auth.getCurrentUser();
setCurrentUser({ user });
}
render() {
return (
<React.Fragment>
<NavBar />
<main className="container">
<Switch>
<Route exact path="/login" component={LoginForm} />
<ProtectedRoute path="/user/:id" component={AddUser} />
<ProtectedRoute exact path="/" component={User} />
<ProtectedRoute exact path="/logout" component={Logout} />
<Route path="/not-found" component={NotFound} />
<Redirect to="/not-found" />
</Switch>
</main>
</React.Fragment>
);
}
}
redux code
const mapDispatchToProps = dispatch => ({
setCurrentUser: user => dispatch(setCurrentUser(user))
});
export default connect(null, mapDispatchToProps)(App);
index.js code
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { BrowserRouter as Router } from "react-router-dom";
import { Provider } from "react-redux";
import store from "./Redux/store";
import * as serviceWorker from "./serviceWorker";
ReactDOM.render(
<Provider store={store}>
<Router>
<App />
</Router>
</Provider>,
document.getElementById("root")
);
/*
If you want your app to work offline and load faster, you can change
unregister() to register() below. Note this comes with some pitfalls. */
serviceWorker.unregister();
Remove the BrowserRouter from the NavBar component.
The Link and the switch must be wrapped in the same Router, which you have already provided around <App/>. The Link inside BrowserRouter( fromNavBar) doesn't have a corresponding switch, that is why the page doesn't change.
Basically, I am learning React Routing with react-router-dom, version 5.0.0 and I have some components like Home, About, Contact etc. and I am trying to change each component by clicking on NavLink but not changing components just changing URL
Indexjs:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import './Style.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import Header from "./components/Header";
import Footer from "./components/Footer";
import Web from "./Web";
ReactDOM.render(
<React.Fragment>
<Header />
<Web />
<Footer />
</React.Fragment>
, document.getElementById('root'));
serviceWorker.register();
Web Componet:
import React, {Component} from 'react';
import {BrowserRouter as Router, Route, Link, NavLink, Redirect, Switch,withRouter} from "react-router-dom";
//import Route from 'react-router-dom/Route';
import {Home} from "./components/Home";
import {About} from "./components/About";
import {Contact} from "./components/Contact";
import {Products} from "./components/Products";
class Web extends Component {
render() {
return (
<Router>
<Switch>
<Route path={"/"} exact component={withRouter(Home)}/>
<Route path={"/products"} component={withRouter(Products)}/>
<Route path={"/about"} component={About}/>
<Route path={"/contact"} component={Contact}/>
<Route path={"/something"} render={
() => {
return (<h1>This is something page</h1>);
}
}/>
</Switch>
</Router>
);
}
}
export default Web;
Header Component:
import React, { Component } from 'react';
import logo from '../logo.jpg';
import {BrowserRouter as Router, Route, Link, NavLink, Redirect} from "react-router-dom";
class Header extends Component {
render() {
return(
<Router>
<header className={'header_area'}>
<div className="container">
<div className="logo">
<img src={logo} alt="logo"/>
</div>
<nav className={'main_nav'}>
<ul>
<li><NavLink to="/" activeStyle={{color:"green"}} exact>Home</NavLink></li>
<li><NavLink to="/products" activeStyle={{color:"green"}} exact>Products</NavLink></li>
<li><NavLink to="/about" activeStyle={{color:"green"}} exact>About</NavLink></li>
<li><NavLink to="/contact" activeStyle={{color:"green"}} exact>Contact</NavLink></li>
</ul>
</nav>
<div className="float_clear"></div>
</div>
</header>
</Router>
);
}
}
export default Header;
Home Component:
import React from 'react';
export class Home extends React.Component {
render() {
return (
<React.Fragment>
<article className={'article_area'}>
<div className="container article">
<h2>Home</h2>
</div>
</article>
</React.Fragment>
);
}
}
About Component:
import React from 'react';
export class About extends React.Component {
render() {
return (
<React.Fragment>
<article className={'article_area'}>
<div className="container article">
<h2>About us</h2>
</div>
</article>
</React.Fragment>
);
}
}
Can anyone help me?
You should use a single Router and all of your routes and links should have it as one of their parents.
Change your index:
<React.Fragment>
<Router>
<Header />
<Web />
<Footer />
</Router>
</React.Fragment>
and remove other <Router>s
Also you do not need to use withRouter for components inside Route. They will get react-router props directly.
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
My site's entering scenario is
/ -> /home
-> /about
-> /project
When connect to site.com/, there is welcome message and enter button.
After click the 'enter' button, /home will be show.
And /home has Navbar that has two components /about and /project
So, user can click the navbar menu to navigate another page.
/about is works properly, but /project doesn't work. It displayed blank page.
[App.js]
import React, { Component } from 'react';
import './App.css';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import Login from './components/Login';
import Home from './components/Home';
import Project from './components/Project';
class App extends Component {
render() {
return (
<Router>
<div className="App">
<Route exact path="/" component={Login} />
<Route path="/home" component={Home} />
</div>
</Router>
);
}
}
export default App;
[Home.js]
import React, { Component } from 'react';
import Header from '../Header';
import Project from '../Project';
import About from '../About';
import 'bootstrap/dist/css/bootstrap.min.css';
import { BrowserRouter, Route } from 'react-router-dom'
import {
Navbar,
NavbarBrand,
Nav,
NavItem,
NavLink } from 'reactstrap';
class index extends Component {
render() {
return (
<BrowserRouter>
<div className="home">
<Header />
<Route path="/home" component={About}/>
<Route path="/project" component={Project}/>
</div>
</BrowserRouter>
);
}
}
export default index;
[Header.js]
import React, { Component } from 'react';
import {
Navbar,
NavbarBrand,
Nav,
NavItem,
NavLink } from 'reactstrap';
class index extends Component {
render() {
return (
<div className="navbar_fixed">
<Navbar color="light" light expand="md">
<NavbarBrand href="/">Hide</NavbarBrand>
<Nav className="ml-auto" navbar>
<NavItem>
<NavLink href="/home">About</NavLink>
</NavItem>
<NavItem>
<NavLink href="/project">Project</NavLink>
</NavItem>
</Nav>
</Navbar>
</div>
);
}
}
export default index;
[About.js]
import React, { Component } from 'react';
import './index.css';
export default class index extends Component {
render() {
return (
<div>
Some codes for About.js
</div>
);
}
}
[Project.js]
import React, { Component } from 'react';
import './index.css';
export default class index extends Component {
render() {
return (
<div>
Some codes for Project.js
</div>
);
}
}
When I entered to /home, It shows About.js component with navbar.
But entered to /project, It show nothing.
I can't find where is the error.
How can I fixed it?
Thanks.
[SOLVED]
Change the code to Shubham Khatri's code and add exact to <Route exact path="/home" component={About}/>
Your Header component isn't receiving the react-router props and hence its navigation doesn't work properly, You could write Header as a default Route. Also you need to use BrowserRouter only once at the top of your App
Also with nested Route, you need to specify the relative routes
class index extends Component {
render() {
const { match } = this.props;
return (
<div className="home">
<Route component={Header} />
<Switch>
<Route path={`${match.path}/project`} component={Project}/>
<Route path="/home" component={About}/>
</Switch>
</div>
);
}
}
and your Header.js will be
import React, { Component } from 'react';
import {
Navbar,
NavbarBrand,
Nav,
NavItem,
NavLink } from 'reactstrap';
class index extends Component {
render() {
const { match } = this.props;
return (
<div className="navbar_fixed">
<Navbar color="light" light expand="md">
<NavbarBrand href="/">Hide</NavbarBrand>
<Nav className="ml-auto" navbar>
<NavItem>
<NavLink href="/home">About</NavLink>
</NavItem>
<NavItem>
<NavLink href={`${match.url}/project`}>Project</NavLink>
</NavItem>
</Nav>
</Navbar>
</div>
);
}
}
export default index;