I am very new to React Js. I want to move from the App Page to the Contact page using react. I tried using the latest useNavigate feature of React . But as soon as I use that hook all the content on my page disappears. I have used the format mentioned in the documentation .
Here is my Code:-
App.Js
import React from "react";
import { useNavigate } from "react-router-dom";
const App = () => {
const navigate = useNavigate();
const goToContact = () => {
navigate('/Contact');
};
return (
<div>
<h1>Hello</h1>
<button onClick={()=>goToContact()}>Contact</button>
</div>
);
};
export default App;
Contact.js
const Contact = () => {
return (
<div>
<h1>Contact</h1>
</div>
);
}
export default Contact;
The file structure
The Output
Don't create the onClick handler as a callback and mention the route in a browser router element so the click gets where to go. To simply navigate would not do that
e.g:
<button onClick={goToContact}>Contact</button>
And for router use this:
<Routes location={location} key={location.pathname}>
<Route path="/Contact" element={<Contact/>} />
</Routes>
Routes and Route are available in react-router-dom v6.
Router needs to be accessed in App.js.
The router will not make any connection between the Contact component and the route '/Contact' on its own. You need to set up your routes to tell the router what it should render for each path. You can do this in App.js for example:
import React from "react";
import { useNavigate } from "react-router-dom";
import Contact from './Contact'
const App = () => {
const navigate = useNavigate();
const goToContact = () => {
navigate('/Contact');
};
return (
<Routes>
<Route path="/" element={(
<div>
<h1>Hello</h1>
<button onClick={()=>goToContact()}>Contact</button>
</div>
)} />
<Route path="/Contact" element={<Contact/>} />
</Routes>
);
};
export default App;
Note that I have moved the content into the "/" path, otherwise you would have that render next to the Contact page. You can set up any content that is repeated on each page (such as navigation) around the <Routes> element.
Related
I am trying to nest a path within another path in react-router-dom version 6 and whenever I try to visit the nested argument's page (/blog/1), it displays a blank non-styles HTML page but when I put a child path to the root ex. /blog it renders perfectly fine.
Example router layout with nested argument:
import React from "React";
import { BrowserRouter, Routes, Route } from "react-router-dom"
import Main from "./pages/Main.tsx";
import ChatGPT from "./pages/ChatGPT.tsx";
const App = () => {
return (
<BrowserRouter>
<Routes>
<Route index element={<Main />} />
<Route path="blog">
<Route path=":id" element={<Blog />} />
</Route>
</Routes>
</BrowserRouter>
);
};
Main.tsx:
import React from "react";
const Main = () => {
return (
<div>
<p>Home page</p>
</div>
);
};
export default Main;
Blog.tsx
import React from "react";
import { useParams } from "react-router-dom";
const Blog = () => {
const params = useParams();
const id = params.id;
return (
<div>
<p>Blog ID: {id}</p>
</div>
);
};
export default Blog;
I tried to put the <Outlet /> tag into the root of my component's <div> tag that didn't work & I was expecting the react to render the nested argument's page correctly. I am also using Webpack's dev server to view the pages.
React: v18.2.0 | React Router DOM: v6.6.2 | Webpack: v5.75.0 | Webpack-cli: v5.0.1 | Webpack-dev-server: 4.11.1
Main and Blog are default exports, which means they are default imports. Calling Main.default or Blog.default is likely returning undefined. Just Render <Main /> and <Blog />.
import React from "React";
import { BrowserRouter, Routes, Route } from "react-router-dom"
import Main from "./pages/Main";
import Blog from "./pages/Blog";
const App = () => {
return (
<BrowserRouter>
<Routes>
<Route index element={<Main />} />
<Route path="blog">
<Route path=":id" element={<Blog />} />
</Route>
</Routes>
</BrowserRouter>
);
};
This question already has an answer here:
how to solve Matched leaf route at location "/project" does not have an element error?
(1 answer)
Closed 27 days ago.
utils.ts:900 Matched leaf route at location "/homepage" does not have an element. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.
When I'm setting up the routes in my react app, empty page is shown in the browser in the url "http://localhost:3002/homepage" and the above warning is shown in the console. What could be the issue?
The respective code for the routing is given below.
App.js
import { Route, Routes } from "react-router-dom";
import io from "socket.io-client";
import { useEffect } from "react";
import Login from "./components/login";
import Homepage from "./components/homepage";
const App = () => {
return (
<div>
<Routes>
<Route path="/homepage" component={<Homepage />} />
</Routes>
</div>
);
};
export default App;`
homepage.js
import React from "react";
const Homepage = () => {
return <h1>Homepage</h1>;
};
export default Homepage;
I'm using react-router-dom#6.7.0.
Try with below example,
const router = createBrowserRouter(
createRoutesFromElements(
<Route path="/homepage" element={<Homepage />}>
</Route>
)
);
Replace App component with below,
const App = () => { return ( <div> <RouterProvider router={router} /> </div> ); };
Also change imports like below,
import { createBrowserRouter, createRoutesFromElements, Route, RouterProvider, } from "react-router-dom";
for more help: https://reactrouter.com/en/main
I am creating a LinkedIn clone where I am adding firebase authentication on the sign-in page. I have added {props.user && <Navigate to="/home" />} where the user contains user information while signing in like name, email, etc.
But due to some reason, when I run yarn start, the sign-in page opens for a fraction of a second and then is redirected to the home page, which goes blank (only we can see the content after refreshing once)
My Login.js:
import styled from "styled-components";
import React from "react";
import { connect } from "react-redux";
import { signInAPI } from "../actions";
import { Navigate } from "react-router";
const Login = (props) => {
return (
<Container>
{props.user && <Navigate to="/home" />}
<Nav>
//other stuff
</Nav>
<Section>
//other stuff
</Section>
</Container>
);
};
//styling code
const mapStateToProps = (state) => {
return {
user: state.userState.user,
};
};
const mapDispatchToProps = (dispatch) => ({
signIn: () => dispatch(signInAPI()),
});
export default connect(mapStateToProps, mapDispatchToProps)(Login);
App.js
import React, { useEffect } from "react";
import Login from "./components/Login";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./components/Home";
import Header from "./components/Header";
import { getUserAuth } from "./actions";
import { connect } from "react-redux";
function App(props) {
useEffect(() => {
props.getUserAuth();
}, []);
return (
<div className="App">
<BrowserRouter>
<Routes>
<Route path="/" element={<Login />}></Route>
</Routes>
</BrowserRouter>
<BrowserRouter>
<Routes>
<Route path="/Home" element={<Home />}></Route>
</Routes>
</BrowserRouter>
</div>
);
}
const mapStateToPorps = (state) => {
return {};
};
const mapDispatchToProps = (dispatch) => ({
getUserAuth: () => dispatch(getUserAuth()),
});
export default connect(mapStateToPorps, mapDispatchToProps)(App);
Yet to complete the whole project so useEffect is not final, still it works
Thought of using <Redirect /> but it doesn't work for newer versions, not even when I reinstalled node_modules, react-router-dom, react-router, it gives this error export 'Redirect' (imported as 'Redirect') was not found in 'react-router'
Don't use 2 routers. The router rendering Login is navigating to a route it doesn't know about so nothing will be matched and render until you reload the page and the other router can read the URL path.
Move all the routes into a single router.
function App(props) {
useEffect(() => {
props.getUserAuth();
}, []);
return (
<div className="App">
<BrowserRouter>
<Routes>
<Route path="/" element={<Login />} />
<Route path="/Home" element={<Home />} />
</Routes>
</BrowserRouter>
</div>
);
}
react-router-dom#6 doesn't export a Redirect component, it was replaced by the Navigate component that serves a similar function. If you want to replicate redirection then you should also pass the replace prop.
const Login = (props) => {
return (
<Container>
{props.user && <Navigate to="/home" replace />}
<Nav>
//other stuff
</Nav>
<Section>
//other stuff
</Section>
</Container>
);
};
If you would like a more conventional route protection implementation then I recommend reviewing this answer regarding implementing protected routes. It decouples route protection from the actual routed content you want to display. It's separation of concerns.
I'm creating a website, and I want the users to be directed to a specific page when they open the site. The page they are going to be directed to depends on if they already logged in. My problem is: the router doesn't work (user is not redirected to any page) and all that appears is a blank page. I've tried to get rid of the routes, but even though, I couldn't display anything on the index page. Maybe the problem is not even the router, but something else.
I never get any error messages. Here are the parts of the code, where I think the problem may be.
_app.js:
import React from 'react'
import { BrowserRouter as Router, Route } from "react-router-dom"
import Novidades from './lancamento'
import SignUp from './signup'
import Croosa from './croosa'
import { AuthProvider } from '../utils/auth'
import PrivateRoute from '../utils/PrivateRoute'
const App = () => {
return(
<AuthProvider>
<Router>
<div>
<PrivateRoute exact path='/lancamento' component={Lancamento} />
<Route exact path='/croosa' component={Croosa}/>
<Route exact path='/signup' component={SignUp} />
</div>
</Router>
</AuthProvider>
)
}
export default App
index.js:
import React from 'react'
import App from './_app'
export default function Home() {
return(
<App/>
)
}
And the PrivateRoute.js, which decides to which page the user is going to be redirected:
import React, { useContext } from "react";
import { Route, Redirect } from "react-router-dom";
import { AuthContext } from "./auth";
const PrivateRoute = ({ component: RouteComponent, ...rest }) => {
const {currentUser} = useContext(AuthContext);
return (
<Route
{...rest}
render={routeProps =>
!!currentUser ? (
<RouteComponent {...routeProps} />
) : (
<Redirect to={"/signup"} />
)
}
/>
)
}
export default PrivateRoute
I would appreciate it if someone could point out my mistake(s).
Next.js uses a filesystem based routing structure.
You have a misunderstanding of how the _app.js file works. It's the parent component that is responsible for rendering the other components that get exported from other pages.
For example: if my _app.js file looks like this:
export default function App({ Component, pageProps }) {
return (
<div>
<p>This was injected by _app.js</p>
<Component {...pageProps} />
<div>
);
}
and my pages/index.js file looks like this:
export default function Hello(){
return <h1>Hello World!</h1>
}
With that setup if I visit the localhost:3000/ then the following will get rendered
<div>
<p>This was injected by _app.js</p>
<h1>Hello World!</h1>
</div>
What you did instead is in your _app.js you ignored the Component property that was passed and so on every page you visit the same content will be rendered. That is:
<AuthProvider>
<Router>
<div>
<PrivateRoute exact path="/lancamento" component={Lancamento} />
<Route exact path="/croosa" component={Croosa} />
<Route exact path="/signup" component={SignUp} />
</div>
</Router>
</AuthProvider>
The reason your index page is blank is because you didn't set up a route for / and so no component will be rendered by react router on that page. Regardless I suggest you stop using react router and start using the built in routing system with next.js
I have two rendering ReactDOM at my index.js
ReactDOM.render(<Header />, document.getElementById('header'));
ReactDOM.render(<App />, document.getElementById('root'));
Now, inside my App.js I have three route
<Router>
<Switch>
<Route exact path = "/" component = { page1 }/>
<Route path = "/page1" component = { page1 }/>
<Route path = "/page2" component = { page2 }/>
</Switch>
</Router>
Then in my Header.js file, I have a button that I want to do a job to navigate to another route or page
<button onClick={() => this.props.history.push('/page2')}> Next </button>
but the problem is I'm having an error saying that
TypeError: Cannot read property 'push' of undefined
I know that it's not in the react router so I can't use the link, but I don't know what should I must do,
The question is, how can I navigate from one route to another using a button that is rendering from another ReactDOM and not inside of the ReactDOM that I wanted to change the route with?
You can create the history object manually with the history library and export that from a separate module that you can give to your Router component and use in your Header component.
Example
// history.js
import createHistory from 'history/createBrowserHistory';
const history = createHistory();
export default history;
// App.js
import history from './history';
export default () => (
<Router history={history}>
<Switch>
<Route exact path = "/" component = { page1 }/>
<Route path = "/page1" component = { page1 }/>
<Route path = "/page2" component = { page2 }/>
</Switch>
</Router>
);
// Header.js
import history from './history';
export default () => (
<button onClick={() => history.push('/page2')}> Next </button>
);
Why not wrapper header component with “withRouter”?
https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/withRouter.md