i am trying to make a navigaton on my website by react-router and typescript. but its not working and instead of Home page i get an empty page
Thats my app.tsx file
// app.tsx
import * as React from 'react';
import '../App.css';
class App extends React.Component<any,any> {
public render() {
return (
<div>
{this.props.children}
</div>
);
}
}
export default App;
index.tsx
// index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import './index.css';
import registerServiceWorker from './registerServiceWorker';
import {AppRouter} from './router';
ReactDOM.render(
<AppRouter/>,
document.getElementById('root') as HTMLElement
);
registerServiceWorker();
router.tsx
import * as React from 'react';
import { Route,Router } from 'react-router';
import App from './components/App';
import HomePage from './components/home/HomePage';
import createHistory from 'history/createBrowserHistory';
const history = createHistory();
export const AppRouter = () => {
return (
<Router history={history}>
<Route path="/" component={App} >
<Route path="/" exact={true} component={HomePage} />
</Route>
</Router>
);
}
i dont really dont know what to say. i cant find any possible info about this. If u know better way to make navigation with typescript, react and redux i am open for ideas. thx
In the App component, you are doing {this.props.children}. So you should not pass that component to any route.
You need to add all the routes as a child of that component through which you will get the children in your props.
Also, for switching between routes, you should bind all the routes in the 'Switch' imported from react-router.
So, your router.tsx file should look like:
import * as React from 'react';
import { Route, Router, Switch } from 'react-router';
import App from './components/App';
import OtherComponent from './components/OtherComponent';
import HomePage from './components/home/HomePage';
import createHistory from 'history/createBrowserHistory';
const history = createHistory();
export const AppRouter = () => {
return (
<App>
<Router history={history}>
<Switch>
<Route exact={true} component={HomePage} />
<Route path="/other" component={OtherComponent} />
</Switch>
</Router>
</App>
);
}
By this, you will get the 'HomePage' component at route '/' and OtherComponent at route '/other'.
Related
When I try using the useLoaderData hook from react-router-dom, it has been giving me the same error
Uncaught Error: useLoaderData must be used within a data router. See
https://reactrouter.com/routers/picking-a-router.
no matter what change I make in the Home Component, so that made me guess the issue is not from there.
This is what my Main.jsx looks like:
import React from 'react'
import ReactDOM from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom'
import App from './App'
import './index.css'
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
)
My App.jsx:
import React from 'react'
import { Route, Routes } from 'react-router-dom'
import Home, { homeLoader } from './pages/Home'
import About from './pages/About'
import GlobalLayout from './GlobalLayout'
const App = () => {
return (
<>
<Routes>
<Route path='/' element={<GlobalLayout />}>
<Route index element={<Home />} loader={homeLoader} />
<Route path='/about' element={<About />} />
</Route>
</Routes>
</>
)
}
export default App
I think everything in my Home.jsx is fine
I have tried checking out the documentation attached to the error and its not helping.
In order to use the RRDv6.4 Data APIs a data router must be used. See Picking a Router.
Use the createBrowserRouter utility to create a Data router. The created router object is passed to the RouterProvider component. Any routes and components that you want or need to use the Data APIs necessarily need to be declared here at build time as part of the data router creation.
App.jsx
import React from 'react';
import {
createBrowserRouter,
createRoutesFromElements,
RouterProvider,
Route,
Routes
} from 'react-router-dom';
import Home, { homeLoader } from './pages/Home';
import About from './pages/About';
import GlobalLayout from './GlobalLayout';
const router = createBrowserRouter(
createRoutesFromElements(
<Route element={<GlobalLayout />}>
<Route path="/" element={<Home />} loader={homeLoader} />
<Route path="/about" element={<About />} />
</Route>
)
);
const App = () => {
return <RouterProvider router={router} />;
};
export default App;
Main.jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './index.css';
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
createBrowserRouter
RouterProvider
createRoutesFromElements
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.querySelector('#root'));
App.js
import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Join from './components/Join';
import Chat from './components/Chat';
const App = () => (
<Routes>
<Route path='/' exact component={Join} />
<Route path='/chat' component={Chat} />
</Routes>
);
export default App;
It thows error like "Error: useRoutes() may be used only in the context of a component."
Here is the ERROR:
"
You have to wrap your app in the BrowserRouter component in order to be able to use routing
So the code in index.js will be as follows
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
ReactDOM.render(<BrowserRouter> <App /> </BrowserRouter>, document.querySelector('#root'));
You could instead wrap the app in App.js
import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Join from './components/Join';
import Chat from './components/Chat';
const App = () => (
<BrowserRouter>
<Routes>
<Route path='/' exact component={Join} />
<Route path='/chat' component={Chat} />
</Routes>
</BrowserRouter>
);
export default App;
but for cleaner code, do the first approach
Wrap your code inside <BrowserRouter> making sure it isn’t in the app itself but higher up in the tree.
I know this question has been asked a lot and I've looked at quite a lot of answers and articles including one on how to upgrade from React Router V5 to V6 since I'm used to V5. However, V6 is giving me a weird issue which I don't know how to fix or what am I doing wrong.
Here's my code below
App.js
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Login from './components/dashboard/Login';
import Profile from './components/dashboard/Profile';
import './resources/style/tutorApp.css';
export default class App extends Component {
static displayName = App.name;
render () {
return (
<Router>
<Routes>
<Route path="/" element={ <Profile /> } />
<Route path="/Login" element={ <Login /> } />
</Routes>
</Router>
);
}
}
Profile.js
import React, { Component } from 'react';
class Profile extends Component {
render() {
return (
<div>
<h1>This is my Profile Page.</h1>
</div>
);
}
}
export default Profile;
Login.js
import React, { Component } from 'react';
class Login extends Component {
render() {
return (
<div>
<h1>This is my Login page.</h1>
</div>
);
}
}
export default Login;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href');
const rootElement = document.getElementById('root');
ReactDOM.render(
<BrowserRouter basename={baseUrl}>
<App />
</BrowserRouter>,
rootElement);
registerServiceWorker();
I just get a blank window in the browser. Nothing is rendered!
What is the problem?
You are mounting a router inside another router.
In ReactDom.render you're wrapping your app in BrowserRouter.
import { BrowserRouter } from 'react-router-dom';
// ...
ReactDOM.render(
<BrowserRouter basename={baseUrl}> // <-- this is the outer browser router
<App />
</BrowserRouter>,
rootElement
);
However inside your app you mount another BrowserRouter in your render method.
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
// ...
render () {
return (
<Router> // <-- this is the nested browser router
<Routes>
<Route path="/" element={ <Profile /> } />
<Route path="/Login" element={ <Login /> } />
</Routes>
</Router>
);
}
To fix the problem simply remove one or the other.
The rest of your code looks fine.
I am switching from react-router 3.x to 4.x and I am not able to render nested routes.
I bootstrapped an application using create-react-app
index.js file
import React from 'react';
import ReactDOM from 'react-dom';
import Routes from './routes';
import './index.css';
ReactDOM.render(<Routes />, document.getElementById('root'));
routes.js file
import React from 'react';
import _ from 'lodash';
import {
BrowserRouter as Router,
Route,
} from 'react-router-dom';
import { dojoRequire } from 'esri-loader';
import EsriLoader from 'esri-loader-react';
import App from './components/App';
import Home from './components/Home';
/**
* Helper component to wrap app
*/
class AppWrapper extends React.Component {
/**
* Util function to render the children
* Whenever a state change happens in react application, react will render the component again
* and we wish to pass the updated state to the children as props
*/
renderChildren() {
const {children} = this.props;
if (!children) {
return;
}
return React.Children.map(children, c => React.cloneElement(c, _.omit(this.props, 'children'), { }));
}
render() {
const child = this.renderChildren();
return (
<App {...this.props}>
{child}
</App>
);
}
}
/**
* Root Loader component to load esri api
*/
class LoaderComponent extends React.Component {
constructor(props) {
super(props);
this.state = { loaded: false };
}
/**
* Callback fired when arc GIS api is loaded
* Now load the requirejs modules using dojorequire
*/
esriReady() {
dojoRequire(['esri/Map', 'esri/views/MapView'], (Map, MapView) => {
this.setState({ Map, MapView, loaded: true });
});
}
render() {
const options = {
url: 'https://js.arcgis.com/4.3/',
};
return (
<div>
<EsriLoader options={options} ready={this.esriReady.bind(this)} />
<AppWrapper {...this.state}>
<Route exact path="/home" component={Home} />
</AppWrapper>
</div>
);
}
};
const Routes = (props) => (
<Router {...props}>
<Route exact path="/" component={LoaderComponent} />
</Router>
);
export default Routes;
App and home components are simple div tags that renders <div>Hello world App</div> and <div>Hello world Home</div>
The App component renders perfectly, but when I navigate to http://localhost:3000/home component I see an empty page.
What I would like to do is
When the user launched the app the user should be redirected to /home and I would like to define two additional routes for App Component
<Route exact path="/a" component={A} />
<Route exact path="/b" component={B} />
Currently I am not able to redirect to /home on app load and not able to define nested routes for App Component.
NOTE: This above code was working fine for react-router version 3.x. To redirect on page load I would use IndexRedirect.
I already had a look at this and this question and I tried all possible solutions in those questions but none is working.
I would like to have all the route handling in routes.js file.
You could achieve such routing with Switch and Redirect:
import React from 'react';
import {Route, Switch, Redirect} from 'react-router-dom';
import {LoaderComponent, AppWrapper , Home, A, B} from './mycomponents';
const routes = (
<LoaderComponent>
<AppWrapper>
<Switch>
<Route exact path='/' render={() => <Redirect to='/home' />} />
<Route exact path='/home' component={Home} />
<Route exact path='/a' component={A} />
<Route exact path='/b' component={B} />
</Switch>
</AppWrapper>
</LoaderComponent>
);
export default routes;
And use the routes.js file something like this:
import React from 'react';
import {render} from 'react-dom';
import {Router} from 'react-router-dom';
import createHistory from 'history/createBrowserHistory';
import routes from './routes';
const history = createHistory();
const App = () =>
<Router history={history}>
{routes}
</Router>;
render(<App />, document.getElementById('root'));
Hey I have implemented react-router-v4, for a simple sample project. here is the github link : How to Implement the react-router-v4. please go through it. very simple.
to run : clone it and hit npm install. hope this will help to you.
I have 3 apps with this structure:
import React from 'react'
export default React.createClass({
render() {
return <div>Hey App1!</div>
}
})
import React from 'react'
export default React.createClass({
render() {
return <div>Hey App2!</div>
}
})
import React from 'react'
export default React.createClass({
render() {
return <div>Hey App3!</div>
}
})
And in my main.js:
import React from 'react'
import ReactDOM from 'react-dom'
import {Router, Route, browserHistory, IndexRoute } from 'react-router'
import App1 from './modules/App1.js'
import App2 from './modules/App2.js'
import App3 from './modules/App3.js'
ReactDOM.render((
<Router history={browserHistory}>
<Route path="/" component={App1}>
<IndexRoute component={App1} />
<Route path="app1" component={App2} />
<Route path="app2" component={App3} />
</Route>
</Router>
), document.getElementById('app'))
But when I try /#/app1 or /#/app2 addresses in my browser it shows the / result (it means 'Hey App1").
My Reactjs version is: 15.3.2
your preferred history is browserHistory. Then the URLs should look like example.com/some/path.
So try /app1 or /app2 without hash in the url.
Hash history uses the hash (#) portion of the URL, creating routes that look like example.com/#/some/path.
If you want to use hash in the url pass hashHistory as props instead of browserHistory