i am new to react and facing a problem. I have a page which contain two tabs. I want to make a hash URL so that it can redirect to corresponding tabs on the basis of url hash. Similarly when i open the page and change a tab, url also updates. Kindly answer in a detailed way as i am new to this and donot know about professional terms.
Moreover i am also bound to use react router for this.
Note: I am using typescript in case it changes something for my solution.
Thanks in advance.
HashRouter uses a hash symbol in the URL, which has the effect of all subsequent URL path content being ignored in the server request (ie you send "www.mywebsite.com/#/person/id" the server gets "www.mywebsite.com". As a result, the server will return the pre # URL response, and then the post # path will be handled by parsed by your client-side react application.
example code :
import React, { Component } from 'react';
import { HashRouter as Router, Route, Link, Switch }
from 'react-router-dom';
import Home from './component/home';
import About from './component/about';
import Contact from './component/contact';
import './App.css';
class App extends Component {
render() {
return (
<Router>
<div className="App">
<ul className="App-header">
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About Us</Link>
</li>
<li>
<Link to="/contact">
Contact Us
</Link>
</li>
</ul>
<Switch>
<Route exact path='/'
component={Home}>
</Route>
<Route exact path='/about'
component={About}>
</Route>
<Route exact path='/contact'
component={Contact}>
</Route>
</Switch>
</div>
</Router>
);
}
}
export default App;
Related
Hope you are doing good. I have one question regarding react routing. I have 5 components defined in app.js file after one by one and created route for that as shown in app.js file and created header for that as well as shown in header.js file. But the problem is this when I should click on the 4th component defined in header then focus should come near to 4th component, instead of displaying 4th component below 5th component. for reference I'm giving one website link I want to make routing like this website, if you didn't understand my question.
Refernce Website link
https://www.styleshout.com/templates/preview/Ceevee_2_0_0/
Note: I have completed this issue, for solution please check this link
https://github.com/pajjwal1/Resume
***App.jS***
import './App.css';
import { Route, Switch} from 'react-router-dom'
import Header from './Components/Header/header';
import Home from './Components/Home/home'
import Bg from './Asset/header-bg.jpg'
import About from './Components/About/about'
import Technical from './Components/Technical/technical'
import Project from './Components/Project/project'
import Education from './Components/Education/education'
import Personal from './Components/Personal/personal'
function App() {
return (
<div className="App">
<Header />
<Home background = {Bg}/>
<About />
<Technical />
<Project />
<Education />
<Personal />
<Switch>
<Route path='/home' exact component={Home}></Route>
<Route path='/about' component={About}></Route>
<Route path='/technical' component={Technical}></Route>
<Route path='/project' component={Project}></Route>
<Route path='/education' component={Education}></Route>
<Route path='/personal' component={Personal}></Route>
</Switch>
</div>
);
}
export default App;
***header.js***
import React from 'react';
import '../Header/header.css'
import {NavLink} from 'react-router-dom'
function header(){
return (
<div className="header">
<div className="header_center">
{/* <p>Home</p>
<p>About</p>
<p>Technical Expertiese</p>
<p>Projects</p>
<p>Qualification</p>
<p>Personal Details</p> */}
<NavLink className='nav-item' to='/home'>Home</NavLink>
<NavLink className='nav-item' to='/about'>About</NavLink>
<NavLink className='nav-item' to='/technical'>Technical Expertiese</NavLink>
<NavLink className='nav-item' to='/project'>Projects</NavLink>
<NavLink className='nav-item' to='/education'>Qualification</NavLink>
<NavLink className='nav-item' to='/personal'>Personal Details</NavLink>
</div>
</div>
);
}
export default header;
I see what you want. Do you want to scroll to the component when you click on the nav item of the header?
In this case, you should use a hash router.
Please put id to each component that you want to navigate on the page.
And use # for hash navigate.
For example, if you want to navigate to projects component, use like this.
<Link to="/#projects"> Projects </Link>
And have you wrapped your app component with Router?
import { createBrowserHistory as history } from 'history'
...
<Router history={history()}>
...
<App />
...
</Router>
I hope this helps you to solve your problem.
If it doesn't work for you, please contact me.
I'm sure I can solve this kind of problem.
I will list the things that I updated on your project.
#app.js
Remove Switch wrapper with children
...
{/* <Switch>
<Route path='/home' exact component={Home}></Route>
<Route path='/about' component={About}></Route>
<Route path='/technical' component={Technical}></Route>
<Route path='/#project' component={Project}></Route>
<Route path='/#education' component={Education}></Route>
<Route path='/personal' component={Personal}></Route>
</Switch> */}
...
#header.js
Please use a tag instead of Navlink
<a className='nav-item' href='/#home'>Home</a>
<a className='nav-item' href='/#about'>About</a>
<a className='nav-item' href='/#technical'>Technical Expertiese</a>
<a className='nav-item' href='/#project'>Projects</a>
<a className='nav-item' href='/#education'>Qualification</a>
<a className='nav-item' href='/#personal'>Personal Details</a>
...
And you should put id on every component as like as the project component.
If it doesn't work, please let me know or invite me to your GitHub repo.
Thanks.
Are you going to scroll down to the component when you click the navigation item on header?
For that you can use hash router.
For more detail about that, you can reference this site.
https://paulgrajewski.medium.com/using-context-and-hashrouter-in-react-87afcefc5966
Is it helpful for you?
So basically, I have a problem with react router not rendering my SystemSidebar. I want to scroll through my SystemSidebar components, but my problem is when I press on 'LinkSoundIcon' it redirects me to 'a new page' but that page doesnt render my systemSidebar . I want when I press on any of the links of my sidebar that my sidebar remains
import React from 'react'
import './SystemSidebar.css'
import SoundIcon from '#material-ui/icons/Computer';
import ComputerIcon from '#material-ui/icons/Computer';
import { BrowserRouter, Route, Switch, Link } from 'react-router-dom';
import Sound from './Sound';
import Computer from './Computer;
const SystemSidebar=()=> {
return (
<div className='system'>
<div className="sidebar">
<Link to='Sound'><VolumeUpIcon /></Link>
<h4> Sound</h4>
<Link to='Computer'><ComputerIcon /></Link>
<h4> Computer</h4>
</div>
</div>
);
};
import React,{Component} from 'react'
import Sound from './Sound';
import Computer from './Computer';
import SystemSidebar from './SystemSidebar';
class MainSystem extends Component {
render(){
return (
<div className="MAIN">
<BrowserRouter>
<SystemSidebar />
<Switch>
<Route exact path="/" component={SystemSidebar} />
<Route exact path="/Sound" component={Sound}/>
<Route exact path="/Computer" component={Computer}/>
</Switch>
</BrowserRouter>
</div>
);
}
}
export default MainSystem;
<Link to='/Sound'><VolumeUpIcon /></Link>
answer of your first problem and second if you want to access sidebar in each component then don't put it in switch route , simply put it outside the routing... or if u want to access it with specific route then try using nested routing
Okay, so it seems a little wonky with your copy pasting (I hope this is just a problem that stems from copy and pasting and it's not like that in your code). But your Problem is here:
<Route exact path="/Sound" component={Sound}/>
You're saying here that the route should be EXACTLY http://<your root uri>/Sound
You should also use this exact route in the link if you want to hit it, this means you need to have the slash there:
<Link to='/Sound'><VolumeUpIcon /></Link>
Update:
So according to your comment you want the sidebar to stay when you click a link. In this case, take a look at your code:
<Switch>
<Route exact path="/" component={SystemSidebar} />
<Route exact path="/Sound" component={Sound}/>
<Route exact path="/Computer" component={Computer}/>
</Switch>
You define here that the component SystemSidebar will only be loaded when you're at the Root directory ("/") of your App. It will be unloaded when you change that directory, for example, to "/Sound". SystemSidebar will be unloaded and Sound will be loaded instead.
Since your Sidebar should always be shown, it needs to be in your Main App and outside of your actual Router logic. Remember what the React Router does: It switches out components depending on which directory (which Sub-URL) you're in. It's best practice to have a Sidebar, an App Bar or similar things that are always there to be their own components. Your actual content should live in a separate container, where the needed component can be swapped out by the Router if need be. So something like this:
class MainSystem extends Component {
render(){
return (
<div className="MAIN">
<SystemSidebar />
<div className="ContentContainer">
<BrowserRouter>
<Switch>
<Route exact path="/Sound" component={Sound}/>
<Route exact path="/Computer" component={Computer}/>
{/* Route "/" should be last because it acts as fallback! */}
<Route exact path="/" component={StartPage} />
</Switch>
</BrowserRouter>
</div>
</div>
);
}
}
That's pretty basic but I hope you get the gist of it.
Also, I'd encourage you to take a look at an UI framework like Material UI for example. It already provides components ready for use (like your Sidebar which is called Drawer there), it's mobile first and easy to use with responsive design.
I've been learning React in my spare time, and in doing so I'm building a project management portal. I have a dashboard route setup at "/" and a projects route setup at "/projects". I want to create a dynamic route for single projects, so have defined this route as "/projects/:id".
The route is working when a go through the navigation like so Home > Projects > [Single Project]. This loads the single project component successfully.
The problem is that when I am on a single project (URL example "/projects/test-project") the main navigation breaks, and every link in the sidebar now starts with "/projects". So when in a single project, and clicking on the main navigation, the links are going to:
/projects/dashboard
/projects/projects
/projects/tasks
/projects/contacts
It's almost like when on a single page, the base URL is brought up a level; so when on a single project, all links in the sidebar are based off the relative path of "projects".
As you can probably tell, I'm finding this issue hard to explain. I've looked at various tutorials on this, and it looks like I'm doing everything correctly. Most tutorials are for React 4, so using class components - I've been through so many assumptions, so anything I can provide to further explain the issue or troubleshoot I'm happy to provide.
I am building the app using functional components and hooks, for what it's worth. In terms of my progress with React so far, this is the biggest thing that is causing me confusion, so any guidance on this would be a massive help.
EDIT
Here's an example of my setup, which shows the problem I'm having: https://codesandbox.io/s/funny-mendeleev-ru5vt
So everything seems to be working if I click through the main navigation. If I navigate to a single project, it breaks every other link except dashboard. Can't figure this one out.
I think your are looking for Nested Routes, as you are using react hooks, please change your route configs as below
import React from "react";
import ReactDOM from "react-dom";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useParams,
useRouteMatch
} from "react-router-dom";
function Topic() {
let { topicId } = useParams();
return (
<div>
<h3>{topicId}</h3>
</div>
);
}
function Topics() {
let { path, url } = useRouteMatch();
return (
<div>
<h2>Topics</h2>
<ul>
<li>
<Link to={`${url}/foo`}>Foo</Link>
</li>
<li>
<Link to={`${url}/bar`}>Bar</Link>
</li>
<li>
<Link to={`${url}/baz`}>Baz</Link>
</li>
</ul>
<Switch>
<Route exact path={path}>
<h3>Please select a topic.</h3>
</Route>
<Route path={`${path}/:topicId`}>
<Topic />
</Route>
</Switch>
</div>
);
}
function App() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
</ul>
<hr />
<Switch>
<Route exact path="/">
<p>Home</p>
</Route>
<Route path="/topics">
<Topics />
</Route>
</Switch>
</div>
</Router>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
UPDATE:
working demo here
I found the answer. It was something critically simple - I hadn't used forward slashes at the start of my navigation links. Router was working the way it should, but just needed to added slashes.
It really is the simplest of things sometimes. Thank to everyone who helped!
The code below will render a link that I can click on, and when I click on it, I can see the URL changing to have /japanese_game for the URL path. However... nothing appears to change on the page, the link that says "Japanese" is still there, unchanged. It should display the other stuff in <Route path="/japanese_game">, or rather, that's what I would like it to do.
What am I doing wrong?
import React from 'react';
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
import './App.css';
function App() {
return (
<div className="App container">
<Router>
<Switch>
<Route path="/">
<Link to="/japanese_game">
<div className="language-option">
Japanese
日本語
</div>
</Link>
</Route>
<Route path="/japanese_game">
<h1>Japanese Game</h1>
<Link to="/">
Go back
</Link>
</Route>
</Switch>
</Router>
</div>
);
}
export default App;
Change the order, it compares and selects on the basis of which matches first. put the Route with "/japanese_game" first.
The <Switch> component render the first route he match (doc).
When you go to /japanese_game, you also hit / route, so he render the component under the / route.
To prevent that, you have 2 options:
Add an exact props to your route / : <Route exact path="/"> (hightly recommanded)
Change the ordre of your route (not recommanded at all)
Change the order of the routes or alternatively use an "exact" flag.
<Route exact path="/japanese_game">
i'm trying to use react router in my reactjs app. And I encountered this problem:
This is what i'm trying to do:
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import About from '../Pages/About';
import Home from '../Pages/Home';
import Topics from '../Pages/Topics';
import LinkTest from '../Pages/LinkTest';
class AppRouter extends Component {
render() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/home">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
<Route path="/home" component={LinkTest}/>
</ul>
<hr />
<Route path="/home" component={Home}/>
<Route path="/about" component={About} />
<Route path="/topics" component={Topics} />
</div>
</Router>
);
}
}
export default AppRouter;
Ignore "about" and "topic" component, when I click on "Home" link, it should target 2 routes, one will render "LinkTest" and the other renders "Home".
This is what inside "LinkTest":
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
class LinkTest extends Component {
render() {
const {match}=this.props;
return (
<div>
<Link to={`${match.url}/Test`}>Link To Test</Link>
</div>
);
}
}
export default LinkTest;
And inside my "Home" component:
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Test from './Test';
class Home extends Component {
render() {
const {match} = this.props;
console.log(match.url);
return (
<Router>
<div>
<h2>
Hello from Home page
<Link to={`${match.url}/Test`}>Link To Test</Link>
<Route path={`${match.url}/Test`} component={Test}/>
</h2>
</div>
</Router>
);
}
}
export default Home;
However:
When i click on the link inside "LinkTest" component (which was rendered earlier), the url on the browser is shown "http://localhost:3000/home/Test", but nothing happens.
When i clicked on the link inside "Home" component, (which was rendered the same time as the "LinkTest" using the same link), it showed the same url on the browser: "http://localhost:3000/home/Test", only this time it rendered the "Test" component.
Why does this happen? (what i want to achieve is I want to use the link inside "LinkTest" to render "Test" component inside "Home" component, or something similar).
I hope this is clear enough.
You can do it in following way:
<Route exact path='/a' component={A} />
<Route path='/b' component={B} />
// Following should be router inside Component B
<Route exact path='/b/abc' component={OtherComponent}
If you want I've prepared few react-router 4 examples. These are hosted here. https://github.com/SandipNirmal/react-router-examples
If you need Nested routing inside ComponentB you should add Links for those Routes as well. And use match.url and match.path to build the nested Links and Routes.
const ComponentB = ({ match }) => {
return (
<div>
<div>
<ul>
<li><Link to={`${match.url}/c`}>Component C</Link></li>
// more Links
<li><Link to={`${match.url}/css`}>CSS</Link></li>
<li><Link to={`${match.url}/react`}>React</Link></li>
</ul>
</div>
<div>
<Route path={`${match.path}/c`} component={ComponentC} />
// more nested Routes
<Route path={`${match.path}/css`} render={() => { return <h1>CSS</h1> }}/>
<Route path={`${match.path}/react`} render={() => { return <h1>React</h1> }}/>
</div>
</div>
);
}
Nested routing
Components created via Route will automatically be passed the following prop objects: match, location and history.
Using match you can implement nested Routes. The match object contains the following properties:
params — (object) Key/value pairs parsed from the URL corresponding
to the dynamic segments of the path
isExact — (boolean) true if the entire URL was matched (no trailing characters)
path — (string) The path pattern used to match. Useful for building nested Routes
url — (string) The matched portion of the URL. Useful for building
nested Links
Reference
https://medium.freecodecamp.org/beginners-guide-to-react-router-4-8959ceb3ad58
https://medium.com/#pshrmn/a-simple-react-router-v4-tutorial-7f23ff27adf