I have configured routes using the React Router in the following way:
<Link to="/">
<Image src={logo} width="200"></Image>
</Link>
Where the above on click routes to the '/' path which is nothing but a Home Component.
Everything is working fine, except that, whenever there is QueryStringparameters, it is routing along with it.
Ideally it should be routed as: http://0.0.0.0:4321/#/
But it is routing as: http://0.0.0.0:4321/?foo=bar#/ keeping the queryParameter intact. I would like to remove this while routing. I am using HashRouter as a prinicipal Router in react.
And this is what I have tried so far:
<Link to="/" onClick={window.history.pushState({}, document.title, window.location.pathname)}>
<Image src={logo} width="200"></Image>
</Link>
But seems like it is not working, what would be the finest way to first remove the queryParameters then route to the Link?
Best practice is to use useHistory hook from 'react-router-dom'
const history = useHistory()
onClick={() => history.push('/')}
Related
I have a "login" screen (entering name only) with the button - without nav links. I want to make an additional screen with different content when the button is clicked, but I can't figure out how to do it.
React version: 18
I tried to add a router, but I didn't know how to set it against the components (I have no links or additional url).
To create a new screen in a React application, you can use a router and add routes for each of the screens in your app.
Install the react-router-dom package, which provides the components and functions you need to use routing in React.
npm install react-router-dom
Import the BrowserRouter, Route, and Link components from the react-router-dom package in your app's entry point (e.g. index.js):
import { BrowserRouter, Route, Link } from 'react-router-dom';
Wrap your app's root component with the BrowserRouter component to enable routing:
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
Add a Route component for each screen in your app, specifying the path for the screen and the component that represents the screen. For example, to add a "Profile" screen, you could do the following:
function App() {
return (
<div>
{/* Other components and content here... */}
<Route path="/profile" component={Profile} />
</div>
);
}
Now add an onClick event on your button e.g
<button type="submit" onClick={onClick}>
Go to Profile
</button>
and this is how you can use:
function LoginForm() {
....
const navigate = useNavigate();
const onClick = () => navigate('/profile');
....
....
}
I am using React Router.
I want when the user clicks on the button, it directs them to the page (endpoint) /form which has the UserForm component.
Here is my code wrapping the button:
<Router>
<Link to="/form" className="updateLink">
<button className="updateBtn" onClick={() => {
this.update(id);
console.log(`Item Number: ${id} Was Updated Successfully`);
window.alert(`Item Number: ${id} Was Updated Successfully`);
}}>U</button>
</Link>
<Switch>
<Router exact path="/form" component={UserForm} />
</Switch>
</Router>
So the reason that doesn't work is because the Button has its own click handler separate from the link handler. You have two options available to you:
Style the Link tag such that it looks like a button but don't actually look like a button (this won't work if you need to do additional logic in addition to routing)
Actually use a button. And then use the 'useHistory' React Hook React Router provides to get the functionality you're looking for.
The component would look something like this:
const history = useHistory()
return (
<Button onClick={() => history.push("/abc")}/>
)
I would personally recommend that you simply style the link tag in the way that you need it to. As that would be more accessible and understandable to the user. But that's only a good idea if you only care about the routing.
Is the above code accurate as in your code?
Router statement should be set up as below, usually in App.js
<Router>
<Switch>
<Route path = './form' component = {form}
</Switch>
</Router>
You then create the form component and to link to it you then import the link component in the component you wish to use it.
Then use as below
<Link to = './form'> Some Text </Link>
Onto the button issue you are having
It will render but you shouldn't nest an <a> or <button> tag in HTML as it wont be sematic for screenreaders, isn't accessible, nor it it valid HTML.
The Link element in react creates and renders an <a> tag which shouldn't be nested in a button.
You could use useHistory in your case for the same effect
import React from 'react'
import { useHistory } from 'react-router-dom'
const component = () => {
const { push } = useHistory()
...
<button
type="button"
onClick={() => push('/form')}>
Click me to go to a form!
</button>
...
}
I decided I need to stop using HasRouter, and instead, use BrowserRouter.
I switched out all my imports from:
import { HashRouter} from 'react-router-dom';
to
import { BrowserRouter } from 'react-router-dom';
As well as all my blocks:
<HashRouter>
to
<BrowserRouter>
My app nearly behaved as expected. All links in my app work fine.
For example:
<Link to={{pathname: `/budget/${item.id}`, state: params}}>{item.name}</Link>
Updated my URL as expected and navigates to the component.
My history works too:
handleEditRow(paymentNumber) {
this.props.history.push(`/schedule/${this.state.scheduleId}/event/${paymentNumber}`);
}
However, all my NavBar buttons fail. The URL updates as expected, but my app does not load the component:
I have my routes in :
return (
<Switch>
<Route exact path="/" component={Dashboard} />
<Route exact path="/accounts" component={Accounts} />
....
</Switch>
)
}
I'm assuming this works, as the links above are behaving.
In my NavBar, I just do simple links:
<Nav.Link as={NavLink} to='/accounts' exact>Accounts</Nav.Link>
I found a link that mentioned to use 'Link' instead of NavLink.
<Nav.Link as={Link} to='/accounts' exact>Accounts</Nav.Link>
But this still fails. URL updates, but page doesn't change.
As I say, the URL changes as expected, but the app does not load the app.
However, if I then select the URL in the address bar, and press Enter (Load the URL that it changed to), the app loads the correct component, as expected.
Can anyone spot my error?
It was working fine with HashRouter.
Just a quick tip: if you're not sure about which Router to use, you can import it aliased as "Router". You then don't have to change all HashRouter references to BrowserRouter if you decide to switch to another Router:
import { BrowserRouter as Router } from 'react-router-dom';
And then use:
<Router>
The advantage of this approach is that you only change the import and it works straight out of the box.
I am currently in process of making a website, and hit a wall on this. I am using react-router-dom for routing my app, and kinda new to it, but in one page, the link that I put on the page does not change the URL
I already tried on previous component, in which I put the button on one component, then use the Link to load another component based on the Link and Route given. However, on this one, despite using similar structure as before, does not work at all
This is the code for the page that loads. I already imported the BrowserRouter as Link from react-router-dom
<div>
<p>TEST</p>
<Link to="/leadslist"><button class="btn btn-success">Back to Leads List</button></Link>
</div>
This is the target page
<div>
<Router>
<Switch>
<Redirect from="/leads" to="/leadslist" />
<Route path="/leadsForm" component={LeadsForm} />
<Route path="/leadslist" component={LeadsList} />
<Route path="/leaddetails" component={LeadsDetails}/>
</Switch>
</Router>
</div>
my previous try clicking button from "/leadslist" to "/leadsForm" actually worked, but then I try to load to "leaddetails" to try to go back to "/leadslist", but it doesn't change the URL at all. Any help will be truly appreciated.
You should not be importing BrowserRoute as Link from the react-router-dom. Both are different things. You need to import Link directly from react-router-dom. Rest, it should work solid.
You should be importing link this way:
import { Link } from "react-router-dom";
Now, I am not sure what's exactly happening your app. But here, I have created a very basic demo or working react-router using CodeSandBox. You can take a look, it should help you fix the problem you are having.
Also, you can read this article to further understand the working of the react router.
Your code doesn't work because you have added button inside Link tag so on click of button React only fires onClick method of button and Link will no be clicked!
So in solution, you can remove a button from Link tag
<Link to="/leadslist">Back to Leads List</Link>
or You can use Below solution,
Instead of adding button in Link You should do this,
import withRouter from 'react-router-dom'
const Component = (props) => {
<div>
<Button onClick={()=>props.history.push('/leadslist')}
</div>
}
export default withRouter(Component)
Add HOC withRouter to your component and you can get history object in prop.
I've decided to use React-Router to manage the routing of my Meteor JS App that uses REACT JS.
I've gotten React-Router to work 'somehow', but it is having some negative side effects that I would like to explain here, in the hopes of finding a solution.
First of all, here is my code:
if (Meteor.isClient) {
Meteor.startup(function () {
console.log('startup');
Hooks.init();
const {Router, Route} = ReactRouter;
const history = ReactRouter.history.useQueries(ReactRouter.history.createHistory)()
React.render((
<Router >
<Route name="home" path="/" component={Sidebar}>
<Route name="managedata" path="managedata" component={ManageData} />
</Route>
</Router>
), document.getElementById("render-target"));
});
}
and in order to navigate between those two routes I've used the Link component provided by React-Router:
<ReactRouter.Link className="item" to="/">
<i className="home icon"></i>
EXAMPLE
</ReactRouter.Link>
<ReactRouter.Link className="item" to="managedata">
<i className="block layout icon"></i>
Manage Data
</ReactRouter.Link>
This is the problem:
1.) Upon loading of the homepage which has the "/" as the path, I am getting random characters showing the URL. This is ugly especially since one would only expect "/" or just nothing to show in the url aside from the domain name or localhost....
e.g. http://localhost:3000/#/?_k=q2c52z
2.) When I click on the Link to 'managedata' I am also getting some random characters in the URL
e.g. http://localhost:3000/#/managedata?_k=6clzfn
Here are my questions:
1.) What is causing those ugly characters to show up in the URL and how do I get rid of them?
2.) Does Link only use the path value? As you can see above, my homepage has a name "home" but a path of "/", I've noticed that if I change the Link to Link to="home" then I get directed to a URL with a "home" on the path which seems to be incorrect.
3.) I ended up using 'component' above as one of the props in Route. I've noticed that many of the examples on the internet uses 'handler'. However, when I use 'handler' in my code.....it doesn't work.....
How are those different?
4.) I've defined my routes as above, but when I use the page does not render initially, but if I click back button on the browser and then click the forward button, then it renders. How do I solve this?
Many hours ago I had the above problems.
Now I've found the solution and I'd like to post it here in the hopes of saving some time for future readers who bump into the same problem.
Here is the Q and A:
1.) What is causing those ugly characters to show up in the URL and how do I get rid of them?
As per https://github.com/rackt/react-router/blob/master/UPGRADE_GUIDE.md
"If you do not specify a history type (as in the example above) then you will notice some unusual behaviour after updating to 1.0.0. With the default hash based routing a querystring entry not defined by yourself will start appearing in your URLs called "_k". An example of how it looks is this: ?_k=umhx1s. "
So add 'history' into the Router.
e.g.
const {Router, Route, IndexRoute} = ReactRouter;
const history = ReactRouter.history.useQueries(ReactRouter.history.createHistory)()
React.render((
<Router history={history}>
<Route path="/" component={Sidebar}>
<IndexRoute component={Dashboard} />
<Route path="managedata" component={ManageData} />
</Route>
</Router>
), document.body);
Notice the history={history} inside the Router.
2.) Does Link only use the path value? As you can see above, my homepage has a name "home" but a path of "/", I've noticed that if I change the Link to Link to="home" then I get directed to a URL with a "home" on the path which seems to be incorrect.
After reading and experimenting....
The value of 'to' should be the path.
Not only should it be the path, it should be the path surrounded by {}.
For example, for the route defined above the Link should be used like this:
<Link to={"/"} className="item" >
<i className="home icon"></i>
EXAMPLE
</Link>
<Link to={"/managedata"} className="item" >
<i className="block layout icon"></i>
Manage Data
</Link>
The surrounding {} made an important difference for me.
Otherwise the page would not render initially....I had to click back and forward again on the browser for the page to render.
3.) I ended up using 'component' above as one of the props in Route. I've noticed that many of the examples on the internet uses 'handler'. However, when I use 'handler' in my code.....it doesn't work..... How are those different?
https://github.com/rackt/react-router/blob/master/UPGRADE_GUIDE.md
Based on the above link, it is the difference between the old API and the new API.
4.) I've defined my routes as above, but when I use the page does not render initially, but if I click back button on the browser and then click the forward button, then it renders. How do I solve this?
I've answered this problem in the answer to number 2.).
But basically, for me, I added {} around the path and it started to render properly.
e.g.
<Link to={"/managedata"} className="item" >
<i className="block layout icon"></i>
Manage Data
</Link>