Given these two components:
import Link from '#material-ui/core/Link';
import { Link } from 'react-router-dom';
Is there a way to get the style from Material-UI with the functionality of react-router-dom?
You can use the component prop of Material-UI's Link to integrate with Link in react-router-dom. You can do the same thing with Material-UI's Button.
Here's an example showing both:
import React from "react";
import { Route } from "react-router";
import { BrowserRouter as Router, Link as RouterLink } from "react-router-dom";
import Link from "#material-ui/core/Link";
import Button from "#material-ui/core/Button";
export default function LinkRouter() {
return (
<Router>
<div>
<Link component={RouterLink} to="/">
Link to Home
</Link>
<br />
<Link component={RouterLink} to="/inner">
Link to inner page
</Link>
<br />
<Button
variant="contained"
color="primary"
component={RouterLink}
to="/inner"
>
Button to inner page
</Button>
<Route path="/" exact>
<div>Here's Home</div>
</Route>
<Route path="/inner">
<div>Here's the inner page</div>
</Route>
</div>
</Router>
);
}
Documentation: https://material-ui.com/guides/composition/#link
I have created a wrapper component to merge both Link so it is not necessary to add the component prop every time.
import { LinkProps, Link as MuiLink } from "#mui/material";
import { Link as ReactRouterLink } from "react-router-dom";
import React, { FC } from "react";
const Link: FC<LinkProps> = props => {
return (
<MuiLink {...props} component={ReactRouterLink} to={props.href ?? "#"} />
);
};
export default Link;
And you can use is as you would use the MUI/LINK:
import Link from './components/Link';
<Link href="path_to_link">LINK</Link>
Related
am trying to build an E-Commerce website with ReactJS(Without any backend or server).
Totally I have 4 components:
Navbar.jsx
Home.jsx
Products.jsx
Cart.jsx
**what i want is, when user clicks on ADD TO CART button in products.jsx, cart number should be displayed on Navbar top right corner but its not displaying.
what i tryed: i just passed props from Products.jsx page to Navbar.jsx but its not working. i tried lot but am unable to do it.. please help me...Thanks in Advance
[am familiar with functional components only]**
CODE : Navbar.jsx
import React from 'react'
import { Link } from 'react-router-dom'
function Navbar(props) {
return (
<div>
<div className="d-flex bg-primary flex-row justify-content-between text-light ">
<div className="left d-flex">
<li className="my-2"><Link className="text-light p-3 py-2" to="/">HOME</Link></li>
<li className="my-2"><Link className="text-light p-3 py-2" to="/products">PRODUCTS</Link></li>
<li className="my-2"><Link className="text-light p-3 py-2" to="/cart">CART</Link></li>
</div>
<div className="right">
<p>CART is:</p><p className="mx-2 h3">{props.text}</p>
{/* I WANT TO DISPLAY THE CART ABOVE HERE */}
</div>
</div>
</div>
)
}
export default Navbar
CODE : Products.jsx
import React, { useState } from 'react'
import Router from '../Router';
import Navbar from './Navbar';
function Products() {
return (
<div>
<h1>PRODUCTS</h1>
<button className="btn btn-success">ADD TO CART</button>
{/* WHEN I CLICK ON ADD TO CART, CART NUMBER SHOULD UPDATED IN NAVBAR */}
</div>
)
}
export default Products
CODE : Router.jsx
import React from 'react'
import {
BrowserRouter,
Switch,
Route,
Link
} from "react-router-dom";
import Home from './components/Home';
import Navbar from './components/Navbar';
import Products from './components/Products';
import Cart from './components/Cart';
function router() {
return (
<>
<BrowserRouter>
{/* <Navbar text="3"/> */}
<Navbar/>
<Switch>
<Route exact path='/' component={Home}/>
<Route exact path='/cart' component={Cart}/>
<Route exact path="/products" component={Products}/>
</Switch>
</BrowserRouter>
</>
)
}
export default router
CODE : index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Home from './components/Home';
import Navbar from './components/Navbar';
import Products from './components/Products';
import './index.css';
import {
BrowserRouter,
Switch,
Route,
Link
} from "react-router-dom";
import Router from './Router';
ReactDOM.render(
<Router />
,
document.getElementById('root')
);
FOLDER STRUCTURE:
folder structure
PLEASE HELP ME...THANKS IN ADVANCE
In Router.jsx, you need to have a state to store cart number
pass this state value as a prop to Navbar.jsx, when this state update, Navbar prop would be update, too
pass setState callback as a prop to Products.jsx, when click "Add To Cart", call this callback, then state value will be updated
Router.jsx
import React, { useState } from "react";
import { BrowserRouter, Switch, Route, Link } from "react-router-dom";
import Home from "./components/Home";
import Navbar from "./components/Navbar";
import Products from "./components/Products";
import Cart from "./components/Cart";
function Router() {
// a state to store cart number
const [text, setText] = useState(3);
return (
<>
<BrowserRouter>
<!-- pass state value as a prop to Navbar -->
<Navbar text={text} />
{/* <Navbar /> */}
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/cart" component={Cart} />
<!-- pass setText callback as a prop to Products -->
<Route
exact
path="/products"
component={() => <Products setText={setText} />}
/>
</Switch>
</BrowserRouter>
</>
);
}
export default Router;
Products.jsx
import React, { useState } from "react";
import Router from "../Router";
import Navbar from "./Navbar";
function Products(props) {
const { setText } = props;
return (
<div>
<h1>PRODUCTS</h1>
<!-- when button click, call setText to update text state -->
<button
className="btn btn-success"
onClick={() => {
setText((prev) => prev + 1);
}}
>
ADD TO CART
</button>
{/* WHEN I CLICK ON ADD TO CART, CART NUMBER SHOULD UPDATED IN NAVBAR */}
</div>
);
}
export default Products;
What you must do is transfer the value to display in the cart from the Products page to the navbar, on button click.
Both Navbar and Products components have a shared parent; Router.jsx. This means your value has to go from Navbar.jsx, up to a state in Router.jsx via a "callback". The state will then be given as the prop to the Navbar.
Following that approach will allow you to dynamically update. To summize; All you need is 1 state in Router, and 1 callback as prob in Navbar, which updates the state in Router.
Header Component
import React from "react";
import { BrowserRouter as Router, Link } from "react-router-dom";
import { ReactComponent as Logo } from "../../asset/crown.svg";
import "./header.scss";
const Header = () => {
return (
<div className='header'>
<Router>
<Link exact className='logo-container' to='/'>
<Logo className='logo' />
</Link>
<div className='options'>
<Link className='option' to='/shop'>
SHOP
</Link>
</div>
</Router>
</div>
);
};
export default Header;
This is my header Component in which I am using Link tag but these tags are changing the URL in the Search Bar but not actually rendering the components.
You don't need the Router inside the Header Component...You can just use Link and then in your App.js setup the Route to the Component. Like So..
App.Js
import React from "react";
import { BrowserRouter as Router, Link } from "react-router-dom";
import { ReactComponent as Logo } from "../../asset/crown.svg";
import "./header.scss";
const Header = () => {
return (
<div className='header'>
<ul>
<li className='logo-container'>
<Link to='/'>
<Logo className='logo' />
</Link>
</li>
<li>
<Link to="/shop">
SHOP
</Link>
</li>
</div>
);
};
export default Header;
//APP COMPONENT
import React from "react";
import { BrowserRouter as Router,Switch, Route } from "react-router-dom";
const App = () => {
return (
<Router>
<Switch>
<Route exact path="/" component="Home">
<Route path="/shop" component="shop">
</Switch>
</Router>
);
};
export default App;
Make sure not to use BrowserRoute inside BrowserRouter.
e.g: when you place a component inside a component it's not JSX there it gets converted to HTML and can cause an error.
Hi im new to react and the routers. The problem is when I click on a link the URL at the top changes so I can tell that something is happening. But the page does not refresh automatically and so the new components arent rendered hen I click on it. If I manually refresh the page in chrome it will then render the correct components for the link. Not sure why this is happening.
Also I'm not sure if this has any affect on it but I do have a back end node js server and MongoDB data base this isn't just a front end react page. Im not sure if that has any affect? the functions of the nodejs server and Mongodb work it just doesn't refresh. Im not sure if that is relevant.
import React , {useState} from 'react';
import logo from './logo.svg';
import './App.css';
import axios from 'axios';
import bootstrap from '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import Register from './Components/Register';
import Login from './Components/Login';
import Notes from './Components/Notes' ;
import Navbar from './Components/Navbar';
import { BrowserRouter, Switch, Route, Link, Redirect } from "react-router-dom";
function App() {
const[getDefault , setDefault] = useState(String);
return (
<div className="App">
<h1>react app</h1>
<Navbar/>
<BrowserRouter>
<div className="App">
<Switch>
<Route path='/app/' component={Register} exact />
<Route path='/app/login/' component={Login} exact/>
<Route path='/app/notes/' component={Notes} exact/>
</Switch>
</div>
</BrowserRouter>
</div>
);
}
/*
<div className='row'>
<div className='col-md-6'>
<Register/>
</div>
<div className='col-md-6'>
<Login/>
</div>
</div>
<div className ='row justify-content-center' >
<div className='col-md-8 '>
<Notes/>
</div>
</div>
*/
export default App;
import React, {useState} from 'react';
import './Navbar.css';
import {Link, Redirect, Router, Switch} from 'react-router-dom';
import { BrowserRouter } from 'react-router-dom';
function Navbar() {
return (<div>
<p style={{color: 'white', fontWeight:'500', fontSize:'50px'}}> Simple Planner </p>
<div className ='navbarOptions' style={{backgroundColor:'black'}}>
<BrowserRouter>
<ul>
<Link to='/app/' exact style={{ fontSize:'30px', color: '#48c6ef', fontWeight: '700'}}>
<li >
Register
</li>
</Link>
<Link to='/app/login/' exact style={{fontSize:'30px', color: '#48c6ef', fontWeight:'700'}}>
<li>
Login
</li>
</Link>
<Link to='/app/notes/' exact style={{fontSize:'30px', color: '#48c6ef' , fontWeight:'700'}}>
<li >
Notes
</li>
</Link>
</ul>
</BrowserRouter>
</div>
</div>
);
}
export default Navbar ;
Here it shows login in the URL but is still rendering notes when I refresh the page it will show notes
You don't need to use browserrouter in the navlink, only use in router and also put the BrowserRouter before the switch
Like this:-
import React , {useState} from 'react';
import logo from './logo.svg';
import './App.css';
import axios from 'axios';
import bootstrap from '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import Register from './Components/Register';
import Login from './Components/Login';
import Notes from './Components/Notes' ;
import Navbar from './Components/Navbar';
import { BrowserRouter, Switch, Route, Link, Redirect } from "react-router-dom";
function App() {
const[getDefault, setDefault] = useState('');
return (
<div className="App">
<h1>react app</h1>
<Navbar/>
<div className="App">
<BrowserRouter>
<Switch>
<Route path='/app/' component={Register} exact />
<Route path='/app/login/' component={Login} exact/>
<Route path='/app/notes/' component={Notes} exact/>
</Switch>
</BrowserRouter>
</div>
</div>
);
}
export default App;
Remove BrowserRouter in your navbar component. I think that should work, normally we have to use BrowserRouter once.
BrowserRouter should wrap all route things, that means that you should put the links within the Browser Router
import React , {useState} from 'react';
import logo from './logo.svg';
import './App.css';
import axios from 'axios';
import bootstrap from '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import Register from './Components/Register';
import Login from './Components/Login';
import Notes from './Components/Notes' ;
import Navbar from './Components/Navbar';
import { BrowserRouter, Switch, Route, Link, Redirect } from "react-router-dom";
function App() {
const[getDefault, setDefault] = useState('');
return (
<div className="App">
<h1>react app</h1>
<BrowserRouter>
<Navbar/>
<div className="App">
<Switch>
<Route path='/app/' component={Register} exact />
<Route path='/app/login/' component={Login} exact/>
<Route path='/app/notes/' component={Notes} exact/>
</Switch>
</div>
</BrowserRouter>
</div>
);
}
export default App;
import React, {useState} from 'react';
import './Navbar.css';
import {Link, Redirect, Router, Switch} from 'react-router-dom';
function Navbar() {
return (
<div>
<p style={{color: 'white', fontWeight:'500', fontSize:'50px'}}> Simple Planner </p>
<div className ='navbarOptions' style={{backgroundColor:'black'}}>
<ul>
<Link to='/app/' exact style={{ fontSize:'30px', color: '#48c6ef', fontWeight: '700'}}>Register</Link>
<Link to='/app/login/' exact style={{fontSize:'30px', color: '#48c6ef', fontWeight:'700'}}>Login</Link>
<Link to='/app/notes/' exact style={{fontSize:'30px', color: '#48c6ef' , fontWeight:'700'}}>Notes</Link>
</ul>
</div>
</div>
);
}
export default Navbar ;
I'm working on a React web application using React router.
In my App.js file i have imported header and home component.
In home component i have 2 components called Onlinebanks and Creditcard that i imported from online-banks.js and creditcard.js files.
When the user clicks link buttons in home.js component, the Onlinebanks and Creditcard components should render.
Instead i am getting an error called Error: Invariant failed: You should not use < Link> outside a < Router>.
Why it's not working?
INDEX.JS
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
APP.JS
import React, { Component } from 'react';
import './App.css';
import Header from './components/header';
import Home from './components/home';
class Routes extends Component {
constructor(props){
super(props);
this.state = {
};
}
render(){
return (
<div className="wrapper">
<Header/>
<Home/>
</div>
);
}
}
export default Routes;
HOME.JS
import React from 'react';
import { Route, Switch, Link } from 'react-router-dom';
import Onlinebanks from './online-banks';
import Creditcard from './creditcard';
const Home = (props) => {
return (
<div className="section">
<div className="main-page">
<div className="tab-container">
<div className="tab-btns">
<Link to="/">
<div className="online-bank-btn">
Online pangad
</div>
</Link>
<Link to="/creditcard">
<div className="creditcard-btn">
Krediitkaart
</div>
</Link>
</div>
<Switch>
<Route path="/" exact component={Onlinebanks}/>
<Route path="/creditcard" exact component={Creditcard}/>
</Switch>
</div>
</div>
</div>
)
}
export default Home;
ONLINE-BANKS.JS
import React from 'react';
const Onlinebanks = (props) => {
return (
<div className="banks-container">
<input type="button" value="Pay" className="pay-btn" id="online-banks-pay"></input>
</div>
)
}
export default Onlinebanks;
CREDITCARD.JS
import React from 'react';
const Creditcard = (props) => {
return (
<div className="Creditcard-container">
<input type="button" value="Pay" className="pay-btn" id="creditcard-pay"></input>
</div>
)
}
export default Creditcard;
I don't see anywhere in your code where you imported BrowserRouter from react-router-dom which should wrap all the other components rendered by your top level componet (app.js) or entirely wrap the app component. so, first import { BrowserRouter as Router } from "react-router-dom" in index.js, then wrap App component with Router as follows
ReactDOM.render(<Router> <App /> </Router>, document.getElementById("root"));
alternatively you can wrap the retun statment in app.js with Router as follows after importing BrowserRouter as Router
return (
<Router>
<div className="wrapper">
<Header/>
<Home/>
</div>
</Router>
);
<Router> is an HOC component, so you need to use it at the top most level possible. Suggestion would be to create a separate Router component and use it within App.js file above div tag
<CustomRouter>
<div className="wrapper">
<Header/>
<Home/>
</div>
</CustomRouter>
you need to better understand how react-router-dom works.
visit here for complete routing guide react-router-dom
i found some major missings in your app.js file.
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
<Route path="/dashboard">
<Dashboard />
</Route>
</Switch>
i don't see this method in your app.js .
This is the code I have, I believe I have imported everything correctly, I am using React mdl to style it and copied and pasted the navbar code.
I also installed react dom router correctly, the individual pages display but the navbar itself doesn't on the landing page.
Can anyone help me? Thanks
App.js
import React, { Component } from "react";
import "./App.css";
import { Layout, Header, Navigation, Drawer, Content } from "react-mdl";
import Earth from "./earth.jpg";
import Main from "./components/main";
import { Link } from "react-router-dom";
class App extends Component {
render() {
return (
<div style={{ height: "300px", position: "relative" }}>
<Layout style={{ background: "src{Earth} center / cover" }}>
<Header transparent title="Title" style={{ color: "white" }}>
<Navigation>
Link
Link
Link
Link
</Navigation>
</Header>
<Drawer title="Title">
<Navigation>
<Link to="/aboutme">About Us</Link>
<Link to="/projects">Projects</Link>
<Link to="/resume">Resume</Link>
<Link to="/contact">Contact</Link>
</Navigation>
</Drawer>
<Content>
<div className="page-content">
<Main />
</div>
</Content>
</Layout>
</div>
);
}
}
export default App;
main.js
import React from 'react';
import { Switch, Route} from 'react-router-dom';
import LandingPage from './landingpage';
import AboutMe from './aboutme';
import Contact from './contact';
import Projects from './projects';
import Resume from './resume';
const Main = () => (
<Switch>
<Route exact path="/" component = {LandingPage} />
<Route path="/aboutme" component = {AboutMe} />
<Route path="/contact" component = {Contact} />
<Route path="/projects" component = {Projects} />
<Route path="/resume" component = {Resume} />
</Switch>
)
export default Main;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import 'react-mdl/extra/material.css';
import 'react-mdl/extra/material.js';
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>
, document.getElementById('root'));
serviceWorker.unregister();
You need to wrap your App component with BrowserRouter from react-router-dom.
You can do this inside you App component, or better in index.js like this:
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(<BrowserRouter><App/></BrowserRouter>, rootElement);
Codesandbox:
https://codesandbox.io/s/so-react-router-uc8dr