In my react project, this is my App.js:
import React from "react";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import Modal from "./Modal";
export default function BasicExample() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
</ul>
<hr />
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/modal">
<Modal />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
return (
<div>
<h2>Home</h2>
<p>
Please <Link to="/modal/1">Click Here</Link> for see details.
</p>
</div>
);
}
When you click on "Click Here", the modal was open, but my home page will be disappear. how can open this modal without destroying the home page ?
DEMO HERE:
https://codesandbox.io/s/react-router-basic-2g9t1
Modals should not be in a route as they are supposed to be on top of another page, not a page themshelves. If you want my opinion I would suggest you to put the modal in any of the pages and control if it is opened or not with a react state:
import React from "react";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import Modal from "./Modal";
export default function BasicExample() {
return (
<Router>
<div>
<Switch>
<Route exact path="/" component={Home} />
</Switch>
</div>
</Router>
);
}
const Home = () => {
const [ isModalOpened, setModalOpened ] = useState(false);
return (
<div>
<h2>Home</h2>
<button onClick={() => setModalOpened(!isModalOpened)}
<Modal isOpened={isModalOpened}>
...modal content here
</Modal>
</div>
);
}
And your modal component should look like something like this:
const Modal = ({ isOpened, children }) => (
<div>
{
isOpened &&
{ children }
}
</div>
)
If this helps you make sure to mark it as a good response!
Related
I am Trying to reach the <Gallery/> Component using a Menu button with React-Router Link
so the code is for the Menu
Menu.jsx
import { Link } from 'react-router-dom';
export default function Menu({ menuOpen, setMenuOpen }) {
return (
<div className={"menu " + (menuOpen && "active")}>
<ul>
<li onClick={() => setMenuOpen(false)}>
<Link to="/">Home Page</Link>
</li>
<li onClick={() => setMenuOpen(false)}>
<Link to="/Gallery">Gallery</Link>
</li>
</ul>
</div>
);
}
and the code for APP.jsx:
import './App.scss';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import { useState } from 'react';
import Gallery from './components/Gallery/Gallery';
import Menu from './components/menu/Menu';
import Topbar from './components/topbar/Topbar';
import FooterComp from './components/Footer/FooterComp';
const App = () => {
const [menuOpen, setMenuOpen] = useState(false);
return (
<>
<Router>
<Topbar menuOpen={menuOpen} setMenuOpen={setMenuOpen} />
<Menu menuOpen={menuOpen} setMenuOpen={setMenuOpen} />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/Gallery" elemtent={<Gallery />} />
</Routes>
<FooterComp />
</Router>
</>
)
}
export default App
When I click the button which is supposed to route to the <Gallery/> Component it routes to an empty component and this warning is displayed in the console
Matched leaf route at location "/Gallery" does not have an element. This means it will render an with a null value by default resulting in an "empty" page.
I searched for this problem and only router-dom version related fixes are there and you can see I'm using the correct v6 props and components.
You have a typo. element
Change
<Route path="/Gallery" elemtent={<Gallery />} />
to
<Route path="/Gallery" element={<Gallery />} />
I'm just new to React and I'm having a hard time figuring out how to return a new page (a component) as I clicked the View button. I have a user table and per row has a View button. I can only retrieve the data in exactly the same page but I would like to retrieve my view details in another page with its id on the url, for example: http://user-details-1. Can someone help me with this. Thanks!
Here's my view code/component:
import React, { useState, useEffect } from "react";
import Form from "react-bootstrap/Form";
const ViewUserDetaiils = (props) => {
const [user, setUser] = useState(props.currentUser);
useEffect(() => {
setUser(props.currentUser);
}, [props]);
return (
<Form>
<div>
<div>
<strong>Id:</strong> {user.id}{" "}
</div>
<div>
<strong>Name:</strong> {user.name}{" "}
</div>
<div>
<strong>Contact:</strong> {user.contact}{" "}
</div>
<div>
<strong>Email:</strong> {user.email}{" "}
</div>
</div>
</Form>
);
};
export default ViewUserDetails;
Here's my routing:
import React, { Component } from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import Home from "./containers/Home/Home";
import ViewUserDetails from "./forms/ViewUserDetails";
import PageNotFound from "./page404/page404";
class App extends Component {
render() {
return (
<BrowserRouter>
<div>
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/home" component={Home} />
<Route
exact
path="/view-contact-details/"
component={ViewUserDetails}
/>
<Route component={PageNotFound} />
</Switch>
</div>
</BrowserRouter>
);
}
}
export default App;
And here's my code for the View button which is in another component(UserTable component).:
<Link to="/view-contact-details">
<Button
onClick={() => {
props.viewRow(user);
}}
className="Button muted-Button"
>
View
</Button>
</Link>
Your route must include a slug (the last part of the URL, in this case the user id) to route it dynamically.
<Route
exact
path="/view-contact-details/:id"
component={ViewUserDetails}
/>
Then in your component's Link you pass an object to attribute to. It accepts a pathname (the path with slug/id included) and state (this contains your state/data).
<Link
to={{
pathname: `/view-contact-details/${user.id}`,
state: { users: user }
}}
>
<button>View</button>
</Link>;
Finally, in your ViewUserDetails component, you can use useLocation to get the state passed in Link.
import React from "react";
import { useLocation, Link } from "react-router-dom";
import Form from "react-bootstrap/Form";
const ViewUserDetails = _ => {
const { state } = useLocation();
return (
<Form>
<div>
<div>
<strong>Id:</strong> {state.users.id}{" "}
</div>
<div>
<strong>Name:</strong> {state.users.name}{" "}
</div>
</div>
</Form>
);
};
export default ViewUserDetails;
Here is a working demo in case you want to check it out.
For those who are facing issues in react-router-dom library v6 (state was displaying null in my case), they can refer this link: here
I've tried all possible versions but goBack() button does not work.
Not sure what I am doing wrong but I was following this solution:
react-router (v4) how to go back?
Anyway here is the code I am trying and I have feeling that there is something to do with HashRouter.
Also How can I put the button in Navbar instead of calling it in App?
import React from 'react';
import { HashRouter, Route, withRouter } from 'react-router-dom';
import Home from "./components/Home";
import Navbar from "./components/Navbar";
import store from './store'
import PrivateRoute from './components/auth/PrivateRoute'
class App extends React.Component {
constructor(props){
super(props);
this.goBack = this.goBack.bind(this); // i think you are missing this
}
componentDidMount(){
store.dispatch(loadUser())
}
goBack(){
this.props.history.goBack();
}
render(){
return (
<Provider store={store}>
<HashRouter basename="/">
<Navbar />
<button onClick={this.goBack()}>Go Back</button>
<Route exact path="/" component={Home}/>
<PrivateRoute path="/aeons" component={AeonsList} />
</HashRouter>
</Provider>
I had an example. Please check it, hope it helps you.
import React from "react";
import {BrowserRouter as Router, Switch, Route, Link} from "react-router-dom";
import {withRouter} from "react-router";
export default function BasicExample() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/about/insideabout">Inside About</Link>
</li>
</ul>
<hr/>
<Switch>
<Route exact path="/">
<Home/>
</Route>
<Route exact path="/about">
<About/>
</Route>
<Route path="/about/insideabout">
<InsideAbout/>
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
return (
<div>
<h2>Home</h2>
</div>
);
}
const About = withRouter(({history, ...props}) => (
<div>
<h1>
About
<hr/>
<button onClick={() => {
// history.push('/')
history.goBack(-1);
}}>go back
</button>
</h1>
</div>
));
const InsideAbout = withRouter(({history, ...props}) => (
<h1 {...props}>
Inside About
<hr/>
<button onClick={() => {
history.goBack();
}}>go back
</button>
<button onClick={() => {
history.go(-2);
}}>go home
</button>
</h1>
));
This how I solved it: Create another component with Go Back button and call it anywhere you want
import React from 'react';
import { withRouter } from 'react-router';
const GoBackButton = withRouter(({history, ...props}) => (
<div>
<button onClick={() => {
// history.push('/')
history.goBack(-1);
}}>go back
</button>
</div>
));
export default GoBackButton
My question might seem stupid because I don't have enough background in React JS.
I have this component:
import { BrowserRouter, Route, NavLink } from "react-router-dom";
import CourseInfo from "./CourseInfo";
import OneCourse from "./OneCourse";
class CourseList extends Component {
render() {
return (
<div>
<BrowserRouter>
<div className="row courses">
{this.props.corses.map(course => (
<NavLink key={course._id} to={`/courses/profile/${course._id}`}>
<OneCourse course={course} />
</NavLink>
))}
</div>
<Route
exact
path={`/courses/profile/:id`}
render={({ match }) => (
<CourseInfo
index={match.params.id}
course={
this.props.corses.filter(el => el._id === match.params.id)[0]
}
/>
)}
/>
</BrowserRouter>
</div>
);
}
}
When I click on OneCourse component, it shows me the CourseList component in the same page with the component CourseInfo added in the bottom.
How can I send user to a new page containing only CourseInfo, knowing that I have parameters to send from this component to CourseInfo?
I want to show CourseInfo component in a different page that doesn't contain the CourseList
<NavLink> is just fine. For the rest, you might use the <Switch> component:
import { BrowserRouter, Route, NavLink, Switch } from 'react-router-dom';
class CourseList extends Component {
render() {
return (
<div>
<BrowserRouter>
<Switch>
<Route
exact
path={`/`} render={({ match }) => (
<div className="row courses">
{this.props.corses.map(course => (
<NavLink key={course._id} to={`/courses/profile/${course._id}`}>
<OneCourse course={course} />
</NavLink>
))}
</div>
)}
/>
<Route
exact
path={`/courses/profile/:id`}
render={({ match }) => (
<CourseInfo
index={match.params.id}
course={
this.props.corses.filter(el => el._id === match.params.id)[0]
}
/>
)}
/>
</Switch>
</BrowserRouter>
</div>
);
}
}
Quoting from the docs:
Switch is unique in that it renders a route exclusively. In contrast, every that matches the location renders inclusively.
With complex routing the render props approach gets confusing. Moving the routing to a separate component is a better approach:
import React from 'react';
import { BrowserRouter, Route, Link, Switch } from "react-router-dom";
import CourseList from './CourseList';
import Course from './Course';
function App() {
return (
<BrowserRouter>
<Switch>
<Route exact path="/" component={CourseList} />
<Route exact path="/courses/profile/:id" component={Course} />
</Switch>
</BrowserRouter>
);
}
export default App;
Then your CourseInfo component looks like:
class CourseList extends Component {
render() {
return (
<div>
<div className="row courses">
{this.props.corses.map(course => (
<NavLink key={course._id} to={`/courses/profile/${course._id}`}>
<OneCourse course={course} />
</NavLink>
))}
</div>
</div>
);
} }
The official documentation provides plenty examples.
I am new to React and I want to navigate to another component on button click. I just want to perform a simple routing. This is the code that I tried. But I am not able to route it.
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom'
import Hello from './HelloComponent';
class App extends Component {
constructor(props) {
super(props);
this.try = this.try.bind(this)
}
try = () => {
alert();
<div>
<Router>
<Route path="/hello" component={Hello} />
</Router>
</div>
}
render() {
return (
<div className="App">
<div className="container">
<button id="b1" onClick={this.try}>Click me</button>
</div>
</div>
);
}
}
export default App;
Please help me with this code to perform basic routing in react JS
You cannot return JSX to onClick handler since it won't do anything with it.
You need to configure your Routes in render in advance and use history.push to change the Route
Below is a sample code that you can refer
import React, { Component } from 'react';
import { BrowserRouter as Router, Route,Switch, Redirect} from 'react-router-dom'
import Hello from './HelloComponent';
class App extends Component {
try = () => {
this.props.history.push('/hello');
}
render() {
return (
<div className="App">
<div className="container">
<button id="b1" onClick ={this.try}>Click me</button>
<Route path="/hello" component={Hello}/>
</div>
</div>
);
}
}
export default () => (
<div>
<Router>
<Route component={App} />
</Router>
</div>
);
I recommend you look at the doc.
<Route path="/hello" component={Hello}/> will display the component Hello exactly where the <Route/> is, but I think your function will do nothing here as it returns a <div> but where does it go?
You need some sort of "higher" component that will render your routes, then call a <Link/>
Then try nesting the button inside the <Link/> ?
<Link to="/??">
<button id="b1">
Click me
</button>
</Link>
in your code
try = () => {
alert();
<div>
<Router>
<Route path="/hello" component={Hello}/>
</Router>
</div>
}
your just pushing the route and it's not a action to take you to different page
bellow code will work fine and it's good practice to place router in separate component. click here you can find this code in codesandbox
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import "./styles.css";
function RouterComponet() {
return (
<Router>
<Switch>
<Route exact path="/" component={App} />
<Route path="/user" component={User} />
</Switch>
</Router>
);
}
class App extends Component {
constructor(props) {
super(props);
}
onClick = () => {
this.props.history.push("/user");
};
render() {
return (
<div>
<h1>App component</h1>
<a onClick={this.onClick} className="link">
click here
</a>{" "}
to user page
</div>
);
}
}
class User extends Component {
constructor(props) {
super(props);
}
onClick = () => {
this.props.history.push("/");
};
render() {
return (
<div>
<h1>User Componet</h1>
<a onClick={this.onClick} className="link">
click here
</a>{" "}
to back
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<RouterComponet />, rootElement);
I have created a demo that brings it all together. It has three files App.js, About.js, Contacts.js. To Navigate to any component, you need to add its route in App.js, Then depending on the location of your button (About.js), wrap it with Link that helps the element navigate to the specified route. When clicked, the Contacts component should be loaded. Hope this helps. code demo
App.js
import React from "react";
import { Switch, Route, BrowserRouter } from "react-router-dom";
import About from "./About";
import Contact from "./Contacts";
function App() {
return (
<BrowserRouter>
<Switch>
<Route path="/" component={About} exact />
<Route path="/contacts" component={Contact} />
</Switch>
</BrowserRouter>
);
}
export default App;
About.js
import React from "react";
import { Link } from "react-router-dom";
function About() {
return (
<div>
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting
industry.
</p>
<Link to="/contacts">
<button>click me</button>
</Link>
</div>
);
}
export default About;
Contacts.js
import React from "react";
function Contact() {
return <div>Call me!!</div>;
}
export default Contact;
This is the first SO post on google, so I'd like answer the question with updated coding style and answer:
From react v6 you use the useNavigation hook. (Reference)
import { useNavigate } from 'react-router-dom';
export const MyComponent = () => {
const navigate = useNavigate();
return (
<>
<button
onClick={() => {
navigate('/');
}}
>
click me
</button>
</>
);
};