React App not routing to the link - javascript

I am new to React and having issues with router. I am just learning from this tutorial: https://medium.com/#thejasonfile/basic-intro-to-react-router-v4-a08ae1ba5c42
Below is the code that is being called from my index.html. When I click on the link 'Show the list', the url changes from localhost:8080 to localhost:8080/list but doesn't really change the context of the page. I am not sure what is going or what I am doing wrong here. Any ideas?
Scripts.js
import React from 'react';
import ReactDOM from 'react-dom';
import {Title, App} from './Components/App';
import { BrowserRouter as Router, Route } from 'react-router-dom';
ReactDOM.render(
<Router>
<div>
<Route exact path="/" component={Title} />
<Route path="/list" component={App} />
</div>
</Router>
, document.getElementById('app'));
App.js
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
const Title = () => {
return (
<div className="title">
<h1>React Router demo</h1>
<Link to="/list">
<button>Show the List</button>
</Link>
</div>
)};
const List = () => {
return (
<div className="nav">
<ul>
<li>list item</li><li>list item</li></ul><Link to="/"><button>Back Home</button></Link></div>)
}
module.exports = {
Title,
List
};

I refactored your code a bit, you should not render the App component for a single page rather your app component should have all the routes like how I made it below. Then as needed add Link throughout your components when you need to navigate and then add the routes in App respectively.
import React, { Component } from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import { Link } from 'react-router-dom';
class App extends Component {
constructor() {
super();
}
render() {
return (
<Router>
<div>
<Route exact path='/home' render={()=> <Title />} > </Route>
<Route exact path='/list' render={() => <List />} > </Route>
</div>
</Router>
);
}
}
const Title = () => {
return (
<div className="title">
<h1>React Router demo</h1>
<Link to="/list">
<button>Show the List</button>
</Link>
</div>
)};
const List = () => {
return (
<div className="nav">
<ul>
<li>list item</li><li>list item</li></ul><Link to='/home'><button>Back Home</button></Link></div>)
}
render(<App />, document.getElementById('app'));
document.getElementById is usually root looks like you changed it to app which is fine.

Related

react-router-dom router change the url but nothing else. All of components are not changed

I can't solve why it doesn't work. When I clck on the link new page the url is changing but the page not (it should change to new page with div witch some content of the new page). I have to refresh it and then the component changes proprely.
version
"react-dom": "^18.1.0",
"react-router-dom": "^5.3.1",
App.js
import React, { Component } from 'react';
import './App.css';
import HomePage from './components/HomePage';
import New from './components/NewComponents';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
function App() {
return (
<div className="App">
<BrowserRouter>
<Switch>
<Route exact path="/" component={HomePage}>
</Route>
<Route patch="/new" component={New}>
</Route>
</Switch>
</BrowserRouter>
</div>
);
}
export default App;
HomePage.js
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
const HomePage = () => {
return (
<div>
<h1>home page</h1>
<Link to="/">home page</Link>
<h1>new page</h1>
<Link to="/New">new page</Link>
</div>
)
}
export default HomePage;
NewComponent.js
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
const New = () => {
return (
<div>
<h1>some content of the new page</h1>
<Link to="/">home</Link>
</div>
)
}
export default New;
You need to add the "/New" route to your switch in the App component:
<Switch>
<Route exact path="/" component={Home}></Route>
<Route path="/create" component={Create}></Route>
<Route path="/New" component={New}></Route>
</Switch>
You also don't import the "Create" component in that module either.

Fetch Param from Route in Nav Bar, React-Router

I have a router set up in my App.js as follows:
import React from 'react';
import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom';
import NavBar from './nav-bar';
import Landing from './landing-page';
import Dashboard from './dashboard';
import Analysis from './analysis';
import '../style.scss';
const App = (props) => {
return (
<Router>
<NavBar />
<Switch>
<Route exact path="/" component={Landing} />
<Route path="/dashboard/:prodID/search" component={Dashboard} />
<Redirect from="/dashboard/:prodID" to="/dashboard/:prodID/search" />
<Route path="/dashboard/:prodID/analyze" component={Analysis} />
<Route component={() => (
<div id="error">
<h1>404 ERROR</h1>
<h2>Page not found</h2>
</div>
)}
/>
</Switch>
</Router>
);
};
export default App;
and my NavBar component is set up as follows:
import React, { Component } from 'react';
import { NavLink, withRouter } from 'react-router-dom';
import { Navbar, Nav } from 'react-bootstrap';
import '../style.scss';
class NavBar extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<Navbar id="nav-bar" bg="dark" variant="dark">
<Navbar.Brand href="/">
My Project
</Navbar.Brand>
<Navbar.Collapse id="responsive-navbar-nav" className="justify-content-end">
<Nav>
<NavLink to="/dashboard/:prodID/search">Search</NavLink>
<NavLink to="/dashboard/:prodID/analyze">Analyze</NavLink>
</Nav>
</Navbar.Collapse>
</Navbar>
);
}
}
export default withRouter(NavBar);
I have two things that I'm trying to figure out:
I want to be able to access the prodID route param within my NavBar component so that when a user clicks on the route, it will take the valid prodID and render the route correctly.
I want to only display the NavLinks in NavBar if the user is on a route that has the prodID param. If they're on the home route / for example, the links wouldn't show up. But if they're on the route /dashboard/[valid prodID]/search, the links would show up.
How do I go about implementing this? I've looked at other posts on SO dealing with route params and nav bars, but none of them have answered my question. Any help is appreciated.
I believe you would have to move your navbar under each of the routes, so that it can be re-rendered and grab the correct params when the path changes.
In order to achieve it, you can create the Layout component which will wrap the component you pass and add a navbar to it:
// Layout.jsx
import React from "react";
import NavBar from './nav-bar';
export const Layout = () => {
return (
<div>
<Navbar />
<div>{children}</div>
</div>
);
};
Then in your App, you can wrap each component within the routes with the Layout component like so
// App.jsx
import React from "react";
import {
BrowserRouter as Router,
Route,
Switch,
Redirect
} from "react-router-dom";
import NavBar from "./nav-bar";
import Landing from "./landing-page";
import Dashboard from "./dashboard";
import Analysis from "./analysis";
import { Layout } from "./Layout";
import "../style.scss";
const App = props => {
return (
<Router>
<Switch>
<Route exact path="/">
<Layout>
<Landing />
</Layout>
</Route>
<Route path="/dashboard/:prodID/search">
<Layout>
<Dashboard />
</Layout>
</Route>
<Redirect from="/dashboard/:prodID" to="/dashboard/:prodID/search" />
<Route path="/dashboard/:prodID/analyze">
<Layout>
<Analysis />
</Layout>
</Route>
<Route
component={() => (
<div id="error">
<h1>404 ERROR</h1>
<h2>Page not found</h2>
</div>
)}
/>
</Switch>
</Router>
);
};
export default App;
This approach would help you achieve your second goal. Since the navbar is now nested under each route, you can easily fetch the params from the path and conditionally render the links, like so:
// NavBar.jsx
import React from "react";
import { NavLink, useParams } from "react-router-dom";
import { Navbar, Nav } from "react-bootstrap";
import "../style.scss";
const NavBar = () => {
const { prodID } = useParams();
return (
<Navbar id="nav-bar" bg="dark" variant="dark">
<Navbar.Brand href="/">My Project</Navbar.Brand>
<Navbar.Collapse
id="responsive-navbar-nav"
className="justify-content-end"
>
<Nav>
{prodID && (
<NavLink to={`/dashboard/:${prodID}/search`}>Search</NavLink>
)}
{prodID && (
<NavLink to={`/dashboard/:${prodID}/analyze`}>Analyze</NavLink>
)}
</Nav>
</Navbar.Collapse>
</Navbar>
);
};
export default NavBar;
I haven't tested it, but it should help you with your issues.

I have two different headers because of Router

So the problem is that I'm new to REACT, I used create-react-app and added a Router function to route between components. Now I created a header which everything was okay with, but I added a hamburger-menu so I could route between my pages and suddenly my Header just got itself duplicated on my webpage.
App.js:
import React, {Component} from 'react';
import { BrowserRouter as Router, Route} from "react-router-dom";
import './App.css';
import './Header.css'
import SideDrawer from "./SideDrawer";
import Header from './Header'
import Backdrop from './Backdrop'
import Home from "./Home";
import LoginPage from "./LoginPage";
import SignupPage from "./SignupPage";
import RegisterEventPage from "./RegisterEventPage";
class App extends Component {
state = {
sideDrawerOpen: false
};
drawerToggleClickHandler = () => {
this.setState((prevState) => {
return {sideDrawerOpen: !prevState.sideDrawerOpen};
});
};
backDropClickHandler = () => {
this.setState({sideDrawerOpen: false});
};
render() {
let sideDrawer;
let backdrop;
if (this.state.sideDrawerOpen) {
sideDrawer = <SideDrawer/>;
backdrop = <Backdrop click={this.backDropClickHandler}/>;
}
return (
<div style={{height: '100%'}}>
<Header drawerClickHandler={this.drawerToggleClickHandler}/>
{sideDrawer}
{backdrop}
<Router>
<Route exact path="/" component={Home}/>
<Route path="/loginPage" component={LoginPage}/>
<Route path="/SignupPage" component={SignupPage}/>
<Route path="/RegisterEventPage" component={RegisterEventPage}/>
</Router>
</div>
);
}
}
export default App;
Header.jsx:
import React, {Component} from 'react';
import DrawerToggleButton from './DrawerToggleButton';
import './Header.css';
class Header extends Component {
render() {
return (
<header className="main_toolbar">
<nav className="toolbar_navigation">
<div>
<DrawerToggleButton click={this.props.drawerClickHandler}/>
</div>
<div className="toolbar_logo">IceBreaker</div>
<div className="spacer"></div>
</nav>
</header>
);
}
}
export default Header;
So if I for example remove from App.js my second header suddenly disappears.
Image of two headers
Render your header inside the router:
I also recomend you to use a switch in your router
You will need to import it :
import { BrowserRouter as Router, Route} from "react-router-dom";
return (
<div style={{height: '100%'}}>
<Router>
<Header drawerClickHandler={this.drawerToggleClickHandler}/>
{sideDrawer}
{backdrop}
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/loginPage" component={LoginPage}/>
<Route path="/SignupPage" component={SignupPage}/>
<Route path="/RegisterEventPage" component={RegisterEventPage}/>
</Switch>
</Router>
</div>
);

React-router v4, URL changing but component doesn't render

I've tried everything but fail to render component when URL changes. No error messages nothing, react-redux is installed but not using it yet, so it can't be the problem. When I check it from to Google chrome React dev tools, nothing happens, there is no match, history vs anything. I couldn't find a solution, is there any way to make it work?
https://codesandbox.io/s/vm3x9n4k67
Here is my NavBar.js. I import NavLink from react-router-dom and implement these
import React from 'react'
import classes from "./NavBar.css";
import { NavLink } from 'react-router-dom';
const NavBar = (props) => {
return (
<div className={classes.NavBar}>
<h1 className={classes.NavBar_list} >foodbase</h1>
<ul className={classes.NavBar_list}>
<NavLink to="/auth"> <li className={classes.NavBar_list_item}>Signin</li></NavLink>
<NavLink to="/"><li className={classes.NavBar_list_item}>Main Page</li></NavLink>
</ul>
</div>
)
}
export default NavBar
this is my Layout.js render property:
render() {
let recipes = [];
if (this.state.recipes.length > 0) {
recipes = this.state.recipes;
}
return (
<div>
<NavBar/>
<SearchBox
onChangeHandler={this.onChangeHandler}
value={this.state.inputValue}
onSearchClick={this.onClickedHandler} />
<section className={classes.SearchSection}>
<ul className={classes.SearchResultArea}>
<SearchResults
Results={recipes}
></SearchResults>
</ul>
</section>
</div>
)
}
and finally app.js:
import React, { Component } from 'react';
import { Switch, Route, BrowserRouter, withRouter } from 'react-router-dom';
import Auth from './components/Auth/Auth';
import SearchBox from './components/SearchBox/SearchBox';
import Layout from './containers/Layout/Layout';
import './App.css';
class App extends Component {
render() {
return (
<div>
<BrowserRouter>
<Switch>
<Layout>
<Route path="/auth" component={Auth} />
<Route path="/" exact component={SearchBox} />
</Layout>
</Switch>
</BrowserRouter>
</div>
);
}
}
export default withRouter(App);
I assume that you need to put your Route components directly into Switch and don't forget to render children in Layout. So try this:
app.js:
class App extends Component {
render() {
return (
<div>
<BrowserRouter>
<Layout>
<Switch>
<Route path="/auth" component={Auth} />
<Route path="/" exact component={SearchBox} />
</Switch>
</Layout>
</BrowserRouter>
</div>
);
}
}
Layout.js
render() {
// ...
return (
<div>
<NavBar />
{ this.props.children } // <-- your route specific components
</div>
)
}

React Router Error: You should not use Route outside of Router

I'm just doing some basic routing in my react app and I've done it this way before so I'm pretty confused to as why it isn't working now.
The error I am getting says: You should not use <Route> or withRouter() outside a <Router>
I'm sure this is super basic so thanks for baring with me!
import React from 'react'
import { Route } from 'react-router-dom'
import { Link } from 'react-router-dom'
import * as BooksAPI from './BooksAPI'
import BookList from './BookList'
import './App.css'
class BooksApp extends React.Component {
state = {
books: []
}
componentDidMount() {
this.getBooks()
}
getBooks = () => {
BooksAPI.getAll().then(data => {
this.setState({
books: data
})
})
}
render() {
return (
<div className="App">
<Route exact path="/" render={() => (
<BookList
books={this.state.books}
/>
)}/>
</div>
)
}
}
export default BooksApp
You need to setup context provider for react-router
import { BrowserRouter, Route, Link } from 'react-router-dom';
// ....
render() {
return (
<BrowserRouter>
<div className="App">
<Route exact path="/" render={() => (
<BookList
books={this.state.books}
/>
)}/>
</div>
</BrowserRouter>
)
}
Side note - BrowserRouter should be placed at the top level of your application and have only a single child.
I was facing the exact same issue. Turns out that i didn't wrap the App inside BrowserRouter before using the Route in App.js.
Here is how i fixed in index.js.
import {BrowserRouter} from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>
document.getElementById('root')
);

Categories