How can I using BrowserRouter instead of HashRouter in react-router v4 - reactjs

const routes = [
{ component: Root,
routes: [
{ path: '/',
exact: true,
component: Home
},
{ path: '/child/:id',
component: Child,
routes: [
{ path: '/child/:id/grand-child',
component: GrandChild
}
]
}
]
}
]
routes.config.js export routes object using in renderRoutes method which is exported by react-router-config
when I start the app and access the url localhost:3000 the Home component will be rendered .
If access localhost:3000/child the request is 404.
If access localhost:3000/#/child but it render Home component instead of Child component
In the development mode I know can add devServer:{historyApiFallback:true}, but should I do in the production mode ?
If using HashRouter it works well.
So how can I using the BrowserRouter?

Try this:
Step 1: Wrap your <App /> inside <BrowserRouter />
Step 2: <Router path="/child" component={Child} />
Step 3: Point this router using <Link to="/CHILD>Child</Link>"

Related

Error in react-router-dom v6.4 not rendering component -> get <URL> not found

Starting my app on --> http://localhost:8000
I created a component called "NavBar", and in this component I created a Link to "/home".
In "/home" Im just rendering the following text --> "Test React Router Dom"
On "NavBar" component, clicking on Link to "/home" it work, but when I try to refresh the page on "/home" or just typing URL: "http://localhost:8000/home" it fails.
"react": "^18.2.0"
"react-dom": "^18.2.0"
"react-router-dom": "^6.4.1"
"typescript": "^4.8.4",
Error -->
// App.tsx
import { NavBar } from './components/NavBar'
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
export const App = () => {
return (
<div>
<Router>
<Routes>
<Route path="/" element={<NavBar />} />
<Route path="/home" element={<h1>Test React Router Dom</h1>} />
</Routes>
</Router>
</div>
)
}
// NavBar.tsx
import './navBar.style.scss'
import { Link } from 'react-router-dom'
export const NavBar = () => {
return (
<>
<Link to={'/home'}>Link to Home</Link>
</>
)
}
//index.tsx
import { createRoot } from 'react-dom/client'
import { App } from './App'
const container = document.getElementById('root') as HTMLElement
const root = createRoot(container)
root.render(<App />)
This will be because your server needs to support HTML5 push state. When you navigate by clicking a link that's using the HTML5 history API (which react-router uses under the hood), its only changing the URL in the address bar -- it doesnt actually try to fetch that page from the server. However when you refresh or hit the URL from the outside of the site, the browser will simply try to load that URL from the server -- there is no client side code even loaded to use the history API.
Your server needs a wildcard route configured such that any and all paths serve your index.html. Then, your JS etc will load, read from the URL, and display the desired page.
If it's an express server you'd need something like this -- but the exact details really depend on your server technology and setup:
app.get('*', function(request, response) {
response.sendfile(__dirname + '/public/index.html');
});
I found a solution, Im using WebPack and I added the following config on Development mode -->
devServer: {
historyApiFallback: true,
}
But I don't understand how "historyApiFallback" works.
Will I need to add some another configuration on my Production mode to prevent the same error?
// webpack.prod.js
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin')
module.exports = {
mode: 'production',
devtool: 'source-map',
devServer: {
historyApiFallback: true,
},
optimization: {
minimizer: [new CssMinimizerPlugin(), new TerserPlugin()],
},
plugins: [],
}

Getting functions from import file within a foreach loop

As im new to Reactjs it is hard for me to explain this, but I am trying to define all pages(components, routes and more) on a different page (routes.js) and looping this on the app.js page in order to build all pages/routes. But the imports of the pages are not working because I didn't defined them on the same page.
When I 'am not using the foreach the pages will load.
//app.js
import RC from './constants/Routes';
import {Page1,Page2,Page3} from "./components/pages";// not used here but set in route.js
<Switch>
{Object.keys(RC).forEach(key=>{
<Route path={RC[key].route} component={RC[key].component}/>
})}
</Switch>
//routes.js
export default Object.freeze({
PAGE1: {
route: '/page1',
component: 'Page1'
},
PAGE2: {
route: '/page2',
component: 'Page2'
},
PAGE3: {
route: '/page3',
component: 'Page3'
},
});

Dynamic route not working in build version of my react app

I use react router for routing in my create-react-app. All routes work as expected using "npm start" ("react-scripts start").
However, now I would like to deploy my application and therefore ran "npm run-scripts build" ("react-scripts build"). Afterwards I ran "serve -s build" in order to start the webserver. In this version of my web application the static routes are working but the dynamic ones don't.
An example of a static route configuration looks like this. This route works in both, the dev mode and the build mode of the react application. Example URL: "http://localhost:5000/dashboard/viewData".
{
path: "/dashboard/viewData/",
component: withAuth(CrosstabTest),
exact: false
}
The following route is dynamic and doesn't work. However, my guess is that it is not due to ":processFlowItemId" but instead due to additional URL parameters. Example URL: "http://localhost:5000/dashboard/definition/1?id=0744a761-111c-446c-9bb5-2763c5c8bb04".
{
path: "/dashboard/definition/:processFlowItemId",
component: withAuth(DefinitionContainer),
exact: false
}
When I run the example URL without "?id=0744a761-111c-446c-9bb5-2763c5c8bb04" the application loads the component but as the id parameter is missing, I get an error. But at least it's an indication for the fact that the route is working in general but has issues with the parameter. When opening the complete example URL including the id field, the component seems not to be loaded at all (meaning react-router doesn't recognize the URL as an instance of the pattern defined in the route.
As mentioned, the issue only occurs when using the build version of the app.
Edit:
Below I describe the code in more details:
I have a config with my routes:
export const mainRoutes: any = [
{
path: "/dashboard/",
component: Dashboard,
exact: false
},
]
export const dashboardRoutes: any = [
{
path: "/dashboard/viewData/",
component: withAuth(CrosstabTest),
exact: false
},
{
path: "/dashboard/definition/:processFlowItemId",
component: withAuth(DefinitionContainer),
exact: false
},
]
The main route ("mainRoute") is rendered here:
import { mainRoutes } from './routes/routes'
import { Switch, BrowserRouter, Route } from 'react-router-dom'
class App extends React.Component<any> {
public render() {
return (
<BrowserRouter>
{mainRoutes.map((route: any, i: number) => (
<Switch key={i}>
<Route key={i} path={route.path} component={route.component} exact={route.exact} />
</Switch>
))
}
</BrowserRouter>
)
}
}
export default App
In the Dashboard component ("Dashboard") I render a subroute:
import { Switch, Route } from 'react-router-dom'
import { dashboardRoutes } from '../../routes/routes'
...
dashboardRoutes.map((route: any, i: number) => (
<Switch key={i}>
< Route exact={true} key={i} path={route.path} render={(props) => {
return <route.component key={i} {...props} />
}} />
</Switch>
))
...
I had the same problem and solved it by exchanging BrowserRouter for HashRouter

How to keep params with react-router v4?

I have a React/Redux Universal application and I have recently added i18next to add internalization to my website.
In my react-router config, I have edited my routes:
const routes = [
{
component: App,
routes: [
{ path: '/:lng(fr|en)?/', exact: true, component: Home },
{ path: '/:lng?/about', component: About },
…
{ component: NotFound }
]
}
];
Everything works well, but I don't know how to keep the lng paramaters between my pages. Indeed, when I use <Link to="/about" >, I logically lost my params.
So, how to keep this parameter?
Thanks

React router - redirect using indexRoute

I'm using react-router with routes parameter:
const rootRoute = {
component: App,
childRoutes: createRoutes(store),
indexRoute: { onEnter: (nextState, replace) => replace('/new-url') }
};
Here is the Router jsx part:
<Router
history={hashHistory}
routes={rootRoute}>
</Router>
The indexRoute is the line I was trying to add to make the redirect but it doesn't work.
You need to add path: '/' to your rootRoute.

Resources