I'm new to react and I have a weird problem that every time I do npm start, I get on the same
page! how do I change it? (tried with few projects! the same page!)
routing:
import { Redirect, Route, Switch } from "react-router-dom";
import { Page404 } from "./Page404";
import { Login } from "./Login";
import { Logout } from "./Logout";
import { Register } from "./Register";
export const Routing = () => {
return (
<div>
<Switch>
<Route path="/login" component={Login} />
<Route path="/logout" component={Logout} />
<Route path="/register" component={Register} />
<Redirect exact from="/" to="/login" />
<Route component={Page404} />
</Switch>
</div>
);
};
and the default route that I always get is:
http://localhost:3000/login-auth
EVERY time after npm start.
btw that started to happen when I installed firebase.
in this project I'm not even using firebase and it keeps happening
Thanks!
first edit
I've noticed that I didn't mention important parts:
first: I don't have a home component yet (wanted to practice log in pages)
second: the app component: which contain the router {i needed the router that way because the header using it as well}
import "./App.css";
import { Routing } from "./Components/Routing";
import "notyf/notyf.min.css";
import { BrowserRouter } from "react-router-dom";
import { MenuBar } from "./Components/MenuBar/MenuBar.jsx";
function App() {
return (
<div className="App">
<BrowserRouter>
<header>
<MenuBar />
</header>
<body>
<Routing />
</body>
</BrowserRouter>
</div>
);
}
I've tried to uninstall firebase (although I'm not using it in this project)
and it did not work as well
** I SOLVED IT! **
I had a "homepage" setting in my package.json that lead me there for some reason
I'm confused, first of all why didnt you rap up your <Switch></Switch> in <Router/> tag?
Mostly the router file structure is like this
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
export default function App() {
return (
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/users">Users</Link>
</li>
</ul>
</nav>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/users">
<Users />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
function Users() {
return <h2>Users</h2>;
}
I think instead of http://localhost:3000/login-auth, you want to see http://localhost:3000. If that's the problem:
It goes to login page because you have <Redirect exact from="/" to="/login" />
Even if you delete this line, you will still face problems, because I cannot see your home component. Where is it?
And also you need to wrap your routing with <Router> and <Switch> tags as ASWIN CHANDRON noted.
Also, I kindly advise you to update your knowledge to new React syntax. And to use exact keyword. So, instead of <Route path="/login" component={Login} /> use <Route exact path="/login"><Login /></Route>
And also instead of import { Login } from "./Login"; you can type import Login from "./Login";
I've solved it, the problem was in the package.json, i had "homepage" option and it just throw me there after npm start
Related
I'm trying to conditionally route the user based on whether they are logged in or not which is checked by my global state variable user. I'm trying to implement this react code into Next.js but I am getting a document reference error. How would I be able to perform the same logic in this code but having it Next.js oriented? Essentially, I don't want to use BrowserRouter.
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'
import { useAuthContext } from 'hooks/useAuthContext';
import HomePage from './home';
import ProductPage from './product';
import LoginPage from './login';
import SignupPage from './signup';
export default function IndexPage() {
const { user } = useAuthContext()
return (
<div>
<BrowserRouter>
<div>
<Routes>
<Route
path="/"
element={<HomePage />}
/>
<Route
path="/login"
element={!user ? <LoginPage /> : <Navigate to="/" />}
/>
<Route
path="/signup"
element={!user ? <SignupPage /> : <Navigate to="/" />}
/>
<Route
path="/product"
element={!user ? <ProductPage /> : <Navigate to="/" />}
/>
</Routes>
</div>
</BrowserRouter>
</div>
);
}
Nextjs has a file based routing system.
If you want to implement protected routing system then it is preferable to use nextjs middleware. (https://nextjs.org/docs/advanced-features/middleware)
Next.js solves those complications. As already mentioned, routings are based on directory. You can refer to the next.js document here.
I'm just starting my first react web app but my components are not rendering. even a simple h1 element directly in the app.js file is not rendering. it did, however, after deleting the Routes, so my best guess is that the problem lies somewhere there.
the code:
app.js
import React, { lazy, Suspense } from 'react'
import './App.css';
import { Routes, Route } from 'react-router-dom'
import { ToastContainer } from 'react-toastify'
import 'react-toastify/dist/ReactToastify.css'
const Home = React.lazy(() => import('./pages/Home'))
const App = () => {
return (
<Suspense fallback={<div>Loading...</div>}>
<h1>App</h1>
<ToastContainer />
<Routes>
<Route exact path="/" element={Home} />
</Routes>
</Suspense>
)
}
export default App;
Home.js
import React from 'react'
const Home = () => {
return (
<h1>Home Page</h1>
)
}
export default Home
sorry for this very beginner question. please keep in mind that this is my first react web app.
React route accepts ReactElement not ReactNode, no need of exact also
<Routes>
<Route path="/" element={<Home />} />
</Routes>
I think that the tutorial you are using uses the previous react-router API. Please, try this:
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useRouteMatch,
useParams
} from "react-router-dom";
export default function App() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
</ul>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
In one of my modules I use this code without any issue:
import { Link } from "react-router-dom";
<Link to="/HowItWorks">
Continue
</Link>
But in another module I use similar code but get the invarient failed message
import { Link } from "react-router-dom";
<Link to="/TheBook">Continue</Link>
The only difference is that the first module is in the src/components directory while the failing module is in the src directory.
In App.js (which is also in src directory) the router code includes several modules including both of the ones above:
import {
Switch,
BrowserRouter as Router,
Route,
Redirect,
} from 'react-router-dom';
import Nav from './Nav';
import Introduction from './components/Introduction.js';
import HowItWorks from './components/HowItWorks.js';
import Blog from './components/Blog.js';
import Shop from './components/Shop.js';
import TheBook from './components/TheBook.js';
import Footer from './Footer.js';
function App() {
return (
<>
<div className="App">
<Router>
<Nav />
<Switch>
<Route path="/Introduction" exact component={Introduction}></Route>
<Route path='/HowItWorks' exact component={HowItWorks}></Route>
<Route path="/Shop" exact component={Shop}></Route>
<Route path="/Blog" exact component={Blog}></Route>
<Route path="/TheBook" exact component={TheBook}></Route>
</Switch>
</Router>
<Footer />
</div>
</>
);
}
export default App;
If I click the link for "TheBook" in the navbar it works fine... Any idea why is this happening ?
Ok, the problem was, as I expected, not in the footer.js code but in the App.js code. The footer.js code needed to be moved inside the Router:
function App() {
return (
<>
<div className="App">
<Router>
<Footer /> {/* The footer must be inside the router for the <link> to work */}
<Nav />
<Switch>
<Route path="/Introduction" exact component={Introduction}></Route>
<Route path='/HowItWorks' exact component={HowItWorks}></Route>
<Route path="/Shop" exact component={Shop}></Route>
<Route path="/Blog" exact component={Blog}></Route>
<Route path="/TheBook" exact component={TheBook}></Route>
</Switch>
</Router>
</div>
</>
);
}
This is now working properly.
I am trying to set redirection to default page, but not works. what is the correct way to do this?
const routes = [
{
path:"/",
component:Home,
extract:"true",
redirect:"/home"
},
{
path:"/home",
component:Home
},
{
path:"/service",
component:Service
}
];
html:
<div>
<Router>
<Header />
{routes.map((route) => (
<Route
key={route.path}
path={route.path}
component={route.component}
/>
))}
</Router>
Assuming you are using react-router-dom, I can see one definitive issue with some additional concerns. You may only need to make one change, but I would advise reviewing the rest of your code to ensure the best routing config.
Main Issue: You have to add a redirect to '/home' if you want that component to be the first page to be loaded. This is because when the app is rendered, it sees the default path as '/'.
<Redirect exact from="/" to="/home" />
<Route path="/home">
<Home />
</Route>
While this may solve your problem by itself, here is a more comprehensive solution that should be beneficial to compare your current code against.
import {
BrowserRouter as Router,
Switch,
Route,
Redirect
} from "react-router-dom";
import home from "./Home";
import service from "./Service";
import header from "./Header";
function App () {
return (
<div>
<Router>
<Header />
<hr />
<Switch>
<Redirect exact from="/" to="/home" />
<Route path="/home">
<Home />
</Route>
<Route exact path="/service">
<Service />
</Route>
</Switch>
</Router>
</div>
);
}
export default App;
As you can see, I would recommend moving the Header outside of the Switch statement and then applying the redirect from / to /home.
Also, please note this configuration is simply an example. It depicts a situation where you are exporting App as a component and does not account for login authorization, so certain aspects of your code may vary.
I am still a newbie to React. So here I am rendering the root component with two routes: Home and About located in functional components: home.js and about.js respectively. However, even after using exact attribute and , the root component keeps on rendering above. I still cannot figure out how to not render the root component when I am redirecting to any of the mentioned routes?
Heres the live demo: https://codesandbox.io/s/vmz6zwq0k7
The Route component is acting like a "placeholder" for the component you want to render when the URL matches. everything above it (parents and siblings) wont get affected.
Given this code example:
render() {
return (
<BrowserRouter>
<div className="App">
<Link to="/home"> Home </Link>{" "}
|
<Link to="/about"> About Us </Link>{" "}
<div>
<Route exact path="/home" component={Home} />
<Route exact path="/about" component={About} />
</div>
</div>
</BrowserRouter>
);
}
This line of code:
<Route exact path="/home" component={Home} />
Is only a "placeholder" for the Home component. It won't render anything only when the path is matching "/home".
When the path will match, the Route component will render the passed component, The Home component in this case.
It will not affect the entire app tree, and for a good reason!
If the entire app would get re-rendered and replaced with the Home component you would loose the navigation links.
I had the same problem looking at the react-routing getting started portion here. https://reactrouter.com/web/guides/quick-start
I placed my Router/BrowserRouter in my App component. Instead place the router in your index.js file like so
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
Then your app component can look like so and the root route wont be matched if about or users is matched.
import React from "react";
import {
Switch,
Route,
Link
} from "react-router-dom";
export default function App() {
return (
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/users">Users</Link>
</li>
</ul>
</nav>
{/* A <Switch> looks through its children <Route>s and
renders the first one that matches the current URL. */}
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/users">
<Users />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
);
}
function Home() {
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
function Users() {
return <h2>Users</h2>;
}