I am rewriting an ASP.NET MVC app to use React with Redux in TypeScript. For routing I am using React Router. The site uses a parameter at to the root to identify the customer's organization.
Example; www.oursite.com/:organizationId with deep links like
www.oursite.com/:organizationId/overview or www.oursite.com/:organizationId/account/:accountId
I have configured React router as below
import * as React from 'react';
import { Router, Route, IndexRoute, HistoryBase } from 'react-router';
import { Layout } from './components/Layout';
import Home from './components/Home';
import OverView from './components/OverView';
import Account from './components/Account';
export default <Route path='/:organizationId' component={ Layout }>
<IndexRoute components={{ body: Home }} />
<Route path='overview' components={{ body: OverView }} />
<Route path='account/:accountId' components={{ body: Account }} />
</Route>;
This works, but any Link components on pages do not, as the root of the app/page is still /.
For example
<Link to={'/overview'} activeClassName='active' />
on the Account control links to www.oursite.com/overview, not www.oursite.com/:organizationId/overview.
Is there a way to configure the React Router to consider /:organizationId/ as the root?
If you take a look at the react router docs it looks like relative links as strings are not supported by react-router. Currently only absolute links are supported.
https://github.com/ReactTraining/react-router/blob/master/docs/API.md#link
However, I think what you are looking for is params. React-router passes down params as props to every component that is connected to a route. For example in your overview component there should params prop. You should be able to do something like
<Link to={`/${this.props.params.organizationId}/overview`></Link>
Let me know if this helps!
Related
In React Router V4, I have a NotFoundScreen component set up to current standards.
It will catch all completely unknown routes fine, but I'm wondering if there is a way to navigate to it without changing the browsers URL. The rest of the app uses typical history.push() URL changing behavior, so I'm not sure I can use the memoryHistory described here: React Router Without Changing URL
To highlight my problem, if a user does not exist, it would be convenient programmatically navigate to NotFoundScreen without changing the users incorrect URL so they could catch a typo or use the browser's back button.
import React from 'react'
import { BrowserRouter, Route, Switch } from "react-router-dom";
import UserScreen from './UserScreen';
import HomeScreen from './HomeScreen';
import NotFoundScreen from './NotFoundScreen';
const Routes = () => {
return (
<BrowserRouter>
<Switch>
<Route exact path='/user/:userID' component={UserScreen}/>
<Route exact path='/' component={HomeScreen}/>
{/*NotFoundScreen will pick up all unknown routes. I want
to navigate here without changing the URL*/}
<Route component={NotFoundScreen}/>
</Switch>
</BrowserRouter>
);
};
export default Routes;
I have react app loaded inside iframe.
this is routing part:
<Router>
<Switch>
<Route path="/" component={View} />
<Route path="/create" component={CreateNewItemPage} />
</Switch>
</Router>
and I use Links inside View.js to navigate:
<Button
variant="contained"
color="primary"
component={Link}
to="/create">
Create
</Button>
Problem is that on click url is changed but view is not changing.
Maybe problem is that it's in iframe not sure. I faced this issue first time.
Tried 'exact' attribute for Route, but same issue.
Also there is no any error in browser console.
The reason might the lack of passing history to Router.
Check Router for more information
Example from Docs:
import React from "react";
import ReactDOM from "react-dom";
import { createBrowserHistory } from "history";
const customHistory = createBrowserHistory();
ReactDOM.render(<Router history={customHistory} />, node);
You could try <BrowserRouter> instead. BrowserRouter is nothing more than the Router with the HTML5 history API. Check BrowserRouter for more info
I hope it fixes your issue. Have a great day.
I am new in react js. So it is a hard problem for me to solve it.
View section does not load on click on navigation links but when URL change manually on the browser then page load working according to url
import AboutUs from './AboutUs';
import News from './News';
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
<Router history={history}>
<Switch>
<Route exact path="/" component={News} />
<Route exact path="/about-us" component={AboutUs} />
</Switch>
</Router>
I have done lots of the way using the different code using the withRouter function but I can not able to solve this issue.
Please help me.
I have fixed my issue. And the issue was in the News and AboutUs components where we have defined the Router inside the router so in the total two-time same router was called in the system. So I have just removed the router related codes from the News and AboutUs component.
You can not define the multiple routers for the same pages with
multiple times.
My react app works as expected for first level routes such as /, /foo, and /bar, both when using the apps navigation menu or when typing the url directly into the browsers address bar.
However deeper urls such as /foo/bar only work when using the apps navigation menu but not when the url is directly input into the browsers address bar.
For depper URLs, When refreshing the page or typing the url directly into the address bar the sites index.html is displayed (a white screen as no content or styles are loaded), but it appears to not be being rendered by react as no errors are present in the console, and the react dev tools show a blank screen.
I am using react-router 4.0.0, and webpack-dev-server with the --history-api-fallback option set. I have tried switching the server to express and setting up a catch all to redirect all routes to the index.html, as well as downgrading to react-router 3.0.2 however the problem persisted in both instances.
I cut my code down to a bare minimum of just the router and a few bare bone components I am trying to route to.
App Entry Point (index.js)
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
// import components
import AppContainer from './components/AppContainer';
render(
<LocaleProvider>
<BrowserRouter>
<AppContainer/>
</BrowserRouter>
</LocaleProvider>,
document.querySelector('#main')
);
AppContainer component
import React from 'react';
import { Route, Switch, Link } from 'react-router-dom';
// import components
import Home from './Home';
import About from './About';
import Test from './Test';
import NotFound from './NotFound';
class AppContainer extends React.Component {
render() {
return (
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/asdasdhuahfisd">404 Test</Link></li>
<li><Link to="/about/test">About/Test</Link></li>
</ul>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about/test" component={Test} />
<Route path="/about" component={About} />
<Route component={NotFound} />
</Switch>
</div>
);
}
}
export default AppContainer;
I managed to narrow down the issue to the html-webpack-plugin that I was using to inject a <script> tag for the generated js file into the body of the app. The script tags src was being generated as a relative url src="main.js", so refreshing the page on deep urls causes the javascript file to not be found, and thus the react app was not loading.
A quick look at html-webpack-plugin code shows that the url for the javascript file is generated from the webpack config variable output.publicPath which I hadn't set in my app. Adding the below code to my webpack.config.js fixed the issue.
output: {
publicPath: '/'
},
I'm using react router to navigate through my application, but I don't want react router to make a call to the server, is that possible?
You should use Hash history.
import { Router, Route } from 'react-router'
import createHashHistory from 'history/lib/createHashHistory'
<Router history={ createHashHistory({ queryKey: false }) }>
<Route path="/" component={App} />
</Router>
If you don't want to use the hash history (which appends a # to the url), use the Link Component which will correctly navigate the App based on the history type passed.