How can I make routing in React, using react-router-dom, using hashbang?
Something like
http://somesite.com/#/home
http://somesite.com/#/about
is fine by me.
In Angular routing, I used { useHash: true } in RouterModule of angular/router to achieve that.
In Vue routing, I used history: createWebHashHistory() in createRouter method of vue-router to achieve that.
Is there a way I achieve that here?
If it's not - please suggest me some other solid routing libraries for React.
P.S. If you wonder why I need it, the answer is IIS. And I don't want to go through overcomplicated procedure of getting it to work on IIS.
You need to use a HashRouter: https://reactrouter.com/web/api/HashRouter
For example, you can do the following:
import { HashRouter as Router, Route, Switch } from 'react-router-dom';
const App = () => {
return (
<Router>
<Switch>
<Route exact path="/foo">
<Component1/>
</Route>
<Route exact path="/bar">
<Component2/>
</Route>
</Switch>
</Router>);
}
Use <HashRouter> instead of one of the other routers.
Related
I have the following react component which I am trying to implement in next.js.
React component:
import React from "react";
import { Route, Switch, Redirect, withRouter } from "react-router-dom";
import Dashboard from "../../pages/dashboard";
import Profile from "../../pages/profile";
function Layout(props) {
return (
<>
<Switch>
<Route
exact
path="/"
render={() => <Redirect to="/app/dashboard" />}
/>
<Route path="/app/dashboard" component={Dashboard} />
<Route path="/app/profile" component={Profile} />
</Switch>
</>
);
}
export default withRouter(Layout);
As I am very new to next. j's, I am not sure on, how can I handle the routes with redirect in next.js similar to above react component code.
Any help is appreciated?
You are using React-Router with NextJS which is possible but not the best practice.
NextJS router is a pretty complicated thing as it handles ClientSide and ServerSide routing simultaneously.
your /app/dashboard and /app/profile pages should render properly. If you want to redirect / to /app/dashboard you can use this trick inside the getInitialProps of the pages/index.js file.
I was building a search engine for custom project.
There I have a search bar from where user can search.
When the user searches, I want the given link to work as it works in case of google
www.google.com/ search? queryRelatedInfo
Notice the search? and then whatever query/parameter/ID
for this I tried something like this in
import React, {Component} from 'react';
import {
BrowserRouter,
Route,
Switch,
Redirect,
} from 'react-router-dom';
import SearchScreen from "./container/searchScreen.js"
import HomeScreen from "./container/home.js";
class route extends Component {
render () {
return (
<BrowserRouter>
<div>
<Switch>
<Route path ="/" exact render ={(props) => <HomeScreen {...props}/>} />
<Route path ="/search?:id" exact render ={(props) => <SearchScreen {...props}/>} />
</Switch>
</div>
</BrowserRouter>
)
}
}
export default route
Notice, <Route path ="/search?:id" above.
Unfortunately this didn't worked out.
I understand that <Route path ="/:id" works but how can i make <Route path ="/search?:id to work i.e how can I make some link like http://localhost:3000/search?9e9e to work
I think this is related with historyApiFallback. That parameter;
(https://webpack.js.org/configuration/dev-server/#devserver-historyapifallback)
When using the HTML5 History API, the index.html page will likely have to be served in place of any 404 responses. devServer.historyApiFallback is disabled by default. Enable it by passing:
module.exports = {
//...
devServer: {
historyApiFallback: true
}
};
Your react app is a single page application. So all path except home path actually is an virtual path, they are not physically exist. The paths must routed to home path. So react-router can manage.
you don't need to put the path like this /search?:id, just put it search
<Route path ="/search" exact render ={(props) => <SearchScreen {...props}/>} />
then inside your SearchScreen component, get the value of search parameter from the URL, check this issue will help.
after the user make search, pass the value like this /search?s=value_here
I am using react router with my application and everything works fine locally. Below is my code. The issue is when I host it online it is in a my-application subdirectory:
https://www.example.com/my-application
This is breaking the code and it is not functioning as it should.
can anyone advise how to fix this issue? If there is anything unclear please feel free to ask. I have tried countless approaches but cannot get it to work. One answer can be seen here.
the issue I am getting is that with the current code it navigates to https://www.example.com/test as opposed to https://www.example.com/my-application/test. I thought if I hardcoded in the url it would work but this also breaks the application.
The code below is slightly whittled down to remove superfluous code.
import React, { Component } from 'react';
import styled from 'styled-components'
import { Route, Switch } from 'react-router-dom'
const Home = ({ avatarUrl }) => {
return (
<div>
<Route exact path="/" component={Overview}/>
<Route path="/test" component={Test}/>
</div>
);
};
class App extends Component {
render() {
return (
<section>
<Nav avatarUrl={ this.props.avatarUrl }/>
<Switch>
<Route path="/example" component={Example}/>
<Route path="/" render={()=><Home
avatarUrl={ avatarUrl }
/>}/>
</Switch>
</section>
)
}
}
export default App
Apply config changes pacakage.json add homepage page as your folder name
To solve this I just did two things:
Added "hostname": "https://www.example.com/my-application" at the top of package.json.
Added basename="my-application" to the BrowserRouter e.g. <BrowserRouter basename="my-application">
Note: I created the project using create-react-app. I am using react version 18 and react-router version 6.
I encountered a problem with React Router v4 Switch component. I'm quite surprised that i couldn't find a relevant thread for this problem. A common Switch will look like this:
<Switch>
<Route path='/path1' component={Path1Component}/>
<Route path='/path2' component={Path2Component}/>
<Route exact path='/' component={Home}/>
<Route component={NotFound}/>
</Switch>
This means that when i'm on a path: '/' i get a Home component, on '/path1' i get a Path1Component and on path '/foobar' i get a NotFound component. And that is perfectly fine
However when i'm on '/path1/foobar' route i also get the Path1Component. This behaviour is not correct in every case - this time i do not want any nested routes for '/path1' route. '/path1/foobar' should get a NotFound component, any string, with '/' or without after '/path1' should return NotFound component.
What would be the preferred resolution to this problem? I could just add exact to every path, but wouldn't that be overbloating the code? I feel like that should be the default, but it's not the case.
Even on React Router v4 docs, like here. I see this problem - here '/will-match/foo' will also match. What are your thoughts?
There is a discussion here, but to make it short : it would break existing code. If this were to change, you'd have to do exact={false} if you want to match child routes without doing 'path1/child1'.
I have this code:
<BrowserRouter>
<Route path="/(:filter)?" component={App} />
</BrowserRouter>
the filter param or '' on the root is suppose to be on App components' props base on the previous react router versions?
This is my code on my App:
const App = ({params}) => {
return ( // destructure params on props
<div>
<AddTodo />
<VisibleTodoList
filter={params.filter || 'all'} // i want to git filter param or assign 'all' on root
/>
<Footer />
</div>
);
}
I logged this.props.match.params on console but it has none? help?
I assume you are following the Redux tutorial on Egghead.io, as your example code seems to use what is defined in that video series. I also got stuck on this part trying to integrate React Router v4, but eventually found a working solution not far from what you have tried.
⚠️ NOTE: one thing I would check here is that you are using the
current version of react-router-dom (4.1.1 at the time of this
writing). I had some issues with optional filters in the params on
some of the alpha and beta versions of v4.
First, some of the answers here are incorrect, and you indeed can use optional params in React Router v4 without the need for regular expressions, multiple paths, archaic syntax, or using the <Switch> component.
<BrowserRouter>
<Route path="/:filter?" component={App} />
</BrowserRouter>
Second, as others have noted, React Router v4 no longer exposes params on route handler components, but instead gives us a match prop to use.
const App = ({ match }) => {
return (
<div>
<AddTodo />
<VisibleTodoList filter={match.params.filter || 'all'} />
<Footer />
</div>
)
}
From here, there are two ways to keep your content in sync with the current route: using mapStateToProps or using the HoC withRouter, both solutions are already talked about in the Egghead series so I won't recapitulate them here.
If you are still having trouble, I urge you to check out my repository of the completed application from that series.
Here is the commit using the mapStateToProps solution
Here is the commit using the withRouter soluiton
Both of which seem to work fine (I just tested both of them).
React Router v4 does not accept a regex for the path. You won't find regular expressions covered anywhere in the documentation. Instead of a regex you can just create multiple routes inside the <Switch> component and the first one that matches will be rendered:
<BrowserRouter>
<Switch>
<Route path="/" component={App} />
<Route path="/:filter" component={App} />
</Switch>
</BrowserRouter>
You also have a bug in your App component. You get the params via the match property, not the params property (not tested, but this should be closer to what you want):
const App = ({match}) => {
return (
<div>
<AddTodo />
<VisibleTodoList
filter={match.params.filter || 'all'}
/>
<Footer />
</div>
);
}
All of the above is covered in the React Router V4 docs on ambiguous matches
From the react-router documentation, props.match.params is where your parameteres are stored.
So to access the filter name, try this
const App = ({match}) => {
...
<VisibleTodoList
filter={match.params.filter || 'all'}
/>
...
}
I know the question is about v4, but if sm looks for v5, we can use the useParams hook.
// /:filter
const {filter} = useParams();
To get the params in the path URL
//to your route component
<Route path={`${match.url}/upload/:title`} component={FileUpload}/>
=====
//Parent component
<Link to={`${match.url}/upload/css`}>
=====
//Child component
const {params: {title}} = this.props.match;
console.log(title);
result = css
I do not know why react router cannot detect my filter even though it's working properly, I resolved this problem by using location.pathname since it does the work for me. I think react router cannot detect my filter param because of regexp, I expected that so I put || to use all on root, but unfortunately for me I it cannot detect so I used location.pathname . I would appreciate suggestions on this since I am not sure with my path configuration on regexp.