I am running an issue where, regardless of what URL I am putting into my browser, I keep getting routed to my main page. I've posted the code below for you to take a look, but my goal is to have my browser take me to my drivers.jsx component when the URL is localhost:3000/drivers. Currently, when I go to localhost:3000/drivers, it renders my _app.jsx component instead :(. Can someone help me understand why I can never render the Drivers component (in drivers.jsx) when I am at localhost:3000/drivers?
index.jsx:
import { BrowserRouter as Router, Routes, Switch, Route } from 'react-router-dom';
import MyApp from './_app.jsx';
import Drivers from './drivers.jsx'
import React, { Component } from 'react'
import { Link } from "../routes.js"
class Home extends Component {
render() {
return (
<Router>
<Switch>
<Route exact path='/drivers' element = {<Drivers />}> </Route>
<Route exact path='/' element = {<MyApp />}> </Route>
</Switch>
</Router>
);
}
}
export default Home;
_app.jsx
import React, { Component } from 'react';
import { useLoadScript } from '#react-google-maps/api';
import Map from '../components/map.jsx';
import "../styles/globals.css";
const MyApp = () => {
const libraries = ['places'];
const {isLoaded} = useLoadScript({
googleMapsApiKey: XXXXXXXXXXXXXX,
libraries
});
if (!isLoaded) return <div>Loading...</div>;
return (
<Map />
);
}
export default MyApp;
drivers.jsx
import React, { Component } from 'react';
class Drivers extends Component {
render() {
return (
<div>TEST</div>
);
}
}
export default Drivers;
I've tried putting the routing logic inside _app.jsx instead, but that causes an incredible amount of errors. My thought is index.js should host all the routing logic, but it shouldn't keep rendering MyApp instead of Drivers when the route is "localhost:3000/drivers".
if your react-router-dom version is
6.4.3
then the switch component dosen't work try changing code to this
instead of using Switch. wrap Route inside Routes
<Router>
<Routes>
<Route path='/drivers' element = {<Drivers />}> />
<Route exact path='/' element = {<MyApp />}> />
</Routes>
</Router>
like this
Related
in Switch Route Routing time it's working, but now latest new Routes, Route it not working custom route
I have wrapped the navbar page and home page in HomeLayoutHOC
can anyone help me :) how to do this latest version I try but so many things. no result for this
I want 'HomeLayoutHOC " route instead of "Route"
->client\src\App.JSX :
//HOC
import HomeLayoutHOC from "./HOC/Home.Hoc";
import { Route, Routes } from "react-router-dom";
//Component
import Temp from "./Components/temp";
function App() {
return (
<>
<Routes>
<HomeLayoutHOC path="/" exact element={Temp} /> // <--- I want this to work!
// <Route path="/" element={<Temp />} /> // <-- this working fine
</Routes>
</>
);
}
export default App;
result 👇
screenshot!
->client\src\index.jsx :
import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import "./index.CSS";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
-> client\src\HOC\Home.Hoc.jsx
import React from "react";
import { Route } from "react-router-dom";
// Layout
import HomeLayout from "../Layout/Home.Layout";
const HomeLayoutHOC = ({ component: Component, ...rest }) => {
return (
<>
<Route
{...rest}
component={(props) => (
<HomeLayout>
<Component {...props} />
</HomeLayout>
)}
/>
</>
);
};
export default HomeLayoutHOC;
->client\src\Layout\Home.Layout.jsx
import React from "react";
// Components
import Navbar from "../Components/Navbar";
const HomeLayout = (props) => {
return (
<>
<Navbar />
<div className="container mx-auto px-4 lg:px-20 ">{props.children}</div>
</>
);
};
export default HomeLayout;
please give me the possible suggestion for the latest router dom (Routes, Route)
wrapping/composing
How can I spread routeProps to make them available to your rendered Component the latest router dom (Routes, Route)
react-router-dom#6 removed the need, and compatibility, for custom route components. It's an invariant violation to render anything other than a Route or React.Fragment component in the Routes component. Custom route components are replaced with the use of either wrapper components on individual routes wrapping the element being rendered, or by layout route components that can wrap any number of nested Route components.
Wrapper components render the children prop
<Route
path="/"
element={(
<Wrapper>
<Componenet />
</Wrapper>
)}
>
Layout Route components render an Outlet component for nested routes to render their element prop into.
<Route element={<Layout />}>
<Route path="/" element={<Componenet />} />
</Route>
You are asking for the Layout Route version since it seems you want to render the Navbar component as part of a greater layout.
HomeLayout
import React from "react";
import { Outlet } from "react-router-dom";
import Navbar from "../Components/Navbar";
const HomeLayout = () => {
return (
<>
<Navbar />
<div className="container mx-auto px-4 lg:px-20 ">
<Outlet />
</div>
</>
);
};
export default HomeLayout;
App
Render HomeLayout on a pathless route as a Layout Route. The nested Route components render their content into the outlet.
import { Route, Routes } from "react-router-dom";
import HomeLayout from "./path/to/HomeLayout";
import Temp from "./Components/temp";
function App() {
return (
<Routes>
<Route element={<HomeLayout />}>
<Route path="/" element={<Temp />} />
... other routes to render with Home layout and Navbar ...
</Route>
... other routes to render without Home layout and Navbar ...
</Routes>
);
}
An important aspect you should notice here is that RRDv6 removed route props, all the old "props" are now only accessible via React hooks in the routed component, i.e. useNavigate, useLocation, useParams, etc. If you are still using React class-based components they won't be able to use React hooks, and since RRDv6 also no longer exports the withRouter Higher Order Component, well, you will need to roll your own. See What happened to withRouter? I need it! for details.
I'm trying to do basic routing in React. Usually what I have done, and what I will mention later on, is use element={<some page>}. But currently I want to learn and experiment what other options there are, so I came across components where you insert a function. I have followed a tutorial and I did the exact same, except the tutorial uses an older version of router dom so it doesn't use Routes.
Here is the code:
App.js:
import {BrowserRouter as Router, Routes, Route} from 'react-router-dom'
import Register from './pages/register';
import Login from './pages/login';
import PageRender from './PageRender';
function App() {
return (
<Router>
<input type='checkbox' id='theme'/>
<div className="App">
<div className="main">
<Routes>
<Route exact path="/:page" component={PageRender}/>
<Route exact path="/:page/:id" component={PageRender}/>
</Routes>
</div>
</div>
</Router>
);
}
export default App;
PageRender.js:
import React from 'react'
import { useParams } from 'react-router'
import NotFound from './components/NotFound'
const generatePage = (pageName) => {
const component = () => require(`./pages/${pageName}`).default
try {
return React.createElement(component())
} catch (err) {
return <NotFound />
}
}
const PageRender = () => {
const {page, id} = useParams()
let pageName = "";
if(id){
pageName = `${page}/[id]`
}else{
pageName = `${page}`
}
return generatePage(pageName)
}
export default PageRender
The login and register js are just basic arrow functions which display login or register (still didn't come to that part). What I want to do is when I enter the url, let's say for instance: http://localhost:3000/register, it sends me to register page and if I enter a wrong path it will send me to the "NotFound" page. But sadly, it doesn't work. I know I can work around this problem if I simply do this:
<Route exact path="/login" element={<Login/>}/>
This method works, but currently I'm in the process of learning and I'm curious why this method didn't work.
I was able to get your code working in react-router-dom v5, the trick was importing the components once in App so they are built/transpiled. The PageRender component worked as-is.
RRDv5
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import './pages/register';
import "./pages/login";
import PageRender from "./PageRender";
export default function App() {
return (
<Router>
<input type="checkbox" id="theme" />
<div className="App">
<div className="main">
<Switch>
<Route path="/:page/:id" component={PageRender} />
<Route path="/:page" component={PageRender} />
</Switch>
</div>
</div>
</Router>
);
}
RRDv6 - Swap the Switch component to the Routes component, and switch to using the element prop instead of the component prop to render the PageRender component as JSX.
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
import './pages/register';
import "./pages/login";
import PageRender from "./PageRender";
export default function App() {
return (
<Router>
<input type="checkbox" id="theme" />
<div className="App">
<div className="main">
<Routes>
<Route path="/:page/:id" element={<PageRender />} />
<Route path="/:page" element={<PageRender />} />
</Routes>
</div>
</div>
</Router>
);
}
I am trying to build a simple meetup application using React.The folder structure is as below:
Inside AllMeetups.js:
function AllMeetupspage(){
return <div>AllMeetups</div>
}
export default AllMeetupspage;
Inside Favourites.js:
function Favouritespage(){
return <div>favourites</div>
}
export default Favouritespage;
Inside Newmeetup.js,
function NewmeetupPage(){
return <div>Newmeetup</div>
}
export default NewmeetupPage;
Inside App.js,
import { Route } from 'react-router-dom';
import AllMeetupspage from './pages/AllMeetups';
import NewmeetupPage from './pages/Newmeetup';
function App() {
return (
<div>
<Route path='/'>
<AllMeetupspage />
</Route>
<Route path='/new-meetup'>
<NewmeetupPage />
</Route>
</div>
);
}
export default App;
Inside index.js,
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root")
);
I want to see the Allmeetups page content when I load browser.But when I load the browser,it displays nothing.I am new to react and javascript.Could anyone please let me know where I go wrong?
If you're using react-router #v6, you need to replace component with element
<Route path="/" element={<AllMeetupspage />} />
...
...
you have to wrap your routes with the BrowserRouter ( in the below image used as Router) from the react-router-dom for the routing to work. I think this is the issue in your code, sorry if am wrong.
Eg:
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
const App = () => {
return (
<>
<Router>
<Switch>
<Route path="/" component={HomePage} />
</Switch>
</Router>
</>
);
};
export default App;
If you are using react-router version#5 or lower you need to do
<Route exact path="/new-meetup" />
because both routes start with the "/" and would always fall back to the first as you don't specify that you want the complete URL match. The exact parameter basically is some kind of regex that says should match the complete url. From the old docs: https://v5.reactrouter.com/web/api/Route/exact-bool
With the version#6 its not necessary anymore as react-router by default will always look for the exact path.
I have a simple app that's using redux and react-router. I wrapped my app component in a provider tag so that it has access to the store. I connected (in App.js) the mapStateToProps and mapStateToDispatch in the App.js. I'm not sure how to pass the function I defined in App.js to a child component since I'm using route. I tried doing the render trick but it didn't work. If I can pass it to that CelebrityPage component, how would I receive it in the file? Any help would be appreciated.
This is my App.js
import React, { Component } from 'react';
import { connect } from 'react-redux'
import './App.css';
import Clarifai from 'clarifai'
// import Particles from 'react-particles-js';
// import particlesOptions from './particleOptions'
import { Signin } from './components/signin/Signin';
import Register from './components/register/Register';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'
import { setSearchField } from './context/Actions'
import FacePage from './Containers/FacePage';
import CelebrityPage from './Containers/CelebrityPage';
import ControllerPage from './Containers/ControllerPage';
const mapStateToProps = state => {
return {
input: state.input
}
}
const mapDispatchToProps = (dispatch) => {
return {
handleSearchChange: (event) => dispatch(setSearchField(event.target.value))
}
}
...
render() {
return (<Router>
<Switch >
<Route path='/celebrity' exact render={props => <CelebrityPage{...props} handleSearchChange={this.handleSearchChange} />} />
<Route path='/' exact component={Register} />
<Route path='/signin' exact component={Signin} />
<Route path='/contoller' exact component={ControllerPage} />
<Route path='/face-detection' exact component={FacePage} />
</Switch>
</Router>)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(App)
If you are going to pass store actions and states into the child components, it means you are refusing to use the advantages of redux. The best approach should be connect any of your component that needs to access to the actions or state to the store. Doing connection at the root component level and passing the props to the child components is not a good solution.
I think what robert is saying is what you'd probably want to do. Don't try to pass your props inside of your <Route>. Instead do your connect mapDispatchToProps and your mapStateToProps inside your CelebrityPage Component.
Once you do the wrapping inside of the Celebrity Page component you should have access to the props and functions that you have defined.
...
// keep all the previous imports from your App.Js
render() {
// have your router like this
return (<Router>
<Switch >
<Route path='/celebrity' exact component ={CelebrityPage} />
<Route path='/' exact component={Register} />
<Route path='/signin' exact component={Signin} />
<Route path='/contoller' exact component={ControllerPage} />
<Route path='/face-detection' exact component={FacePage} />
</Switch>
</Router>)
}
}
export default App
Example Celebrity page
import React from 'react'
import { connect } from 'react-redux'
class CelebrityPage extends React.Component {
// put your mapStateToProps and mapDispatch function heres instead of app.js
mapStateToProps() {
}
mapDispatchToProps {
// bind your handlesearch function to props here
}
render() {
return (
<div>
<input />
<button onClick={this.props.handleSearchChange}/>
</div>
)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(CelebrityPage)
I'm failing at passing a property from a <Route />
Here is some code :
./app.jsx (main app)
import React from 'react'
import { render } from 'react-dom'
import { Router, Route, IndexRoute } from 'react-router'
import App from './components/app'
import Home from './components/home'
import About from './components/about'
render((
<Router>
<Route path="/" component={App}>
<IndexRoute component={Home} title="Home" />
<Route path="about" component={About} title="About" />
</Route>
</Router>
), document.getElementById('app'))
./components/app.jsx
import React from 'react';
import Header from './template/header'
class App extends React.Component {
render() {
return (
<div>
<Header title={this.props.title} />
{this.props.children}
</div>
)
}
}
export default App
./components/template/header.jsx
import React from 'react'
class Header extends React.Component {
render() {
return (
<span>{this.props.title}</span>
)
}
}
export default Header
When I click on my home route* I want my Header component to display Home.
When I click on my about route I want my Header component to display About.
At this point, my Header components displays nothing. this.props.title is undefined in my App component.
Looks like you can't pass an attribute from a <Route />
Is there a way to achieve this?
Or is there another way? For instance, can you get something from the children element (this.props.children.title or something like that) ?
It looks like the route injects a routes property with a list of the matching routes. The last route in the list has the props you specify. See http://codepen.io/anon/pen/obZzBa?editors=001
const routes = this.props.routes;
const lastRoute = routes[routes.length - 1];
const title = lastRoute.title;
I'd hesitate a little to use this, since routes is not documented in the Injected Props, so I don't know how reliable it is across version updates. A simpler option, though not as legible, would be to use this.props.location.pathname and maintain a lookup table for titles.
The best and most flexible option is probably the boilerplate-heavy one, where you define the template and then reuse it across components:
class Template extends React.Component {
render() {
return (
<div>
<Header title={this.props.title} />
{this.props.children}
</div>
)
}
}
class About extends React.Component {
render() {
return (
<Template title="About">
Some Content
</div>
)
}
}