Reputation: 260
I want to implement side bar and wrap them in a div only for few routes. The other routes should not be having the sidebar.
all the pages from top was working except the * wildcard route. Console it says React does not recognize the computedMatch
prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase computedmatch
instead. If you accidentally passed it from a parent component, remove it from the DOM element.
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
withRouter,
} from "react-router-dom";
import Header from "./components/header";
import LoginPage from "./pages/login";
import DashboardPage from "./pages/dashboard";
import NotfoundPage from "./pages/notfound";
export default function App() {
return (
<Router>
<Header />
<Switch>
<Route exact path="/" component={LoginPage} />
<main className="dashboardMain">
<React.Fragment>
<SideBar />
<Route
exact
path="/dashboard"
component={withRouter(DashboardPage)}
/>
</React.Fragment>
</main>
<Route path="*" component={NotfoundPage} />
</Switch>
</Router>
);
}
Upvotes: 0
Views: 1089
Reputation: 1439
I once have stumbled the same issue. Maybe because we didn't suppose to have nested element in between Route
(I'm not sure about this tho). Anyway, this is the fixes I did to my system:-
component
.component
which gonna act as a parent OR wrapper for all our Switch
& Route
.Route
should have sidebar & which don't.For the following example, I use Context API
which oversee whether user
already login
or not. Only loggedIn user will have access to sidebar. To make this work, We're gonna need to make some of our Route
protected. See the implementation below:-
App.js
(We will import Nav
as new external parent or wrapper component
for all our Switch
& Route
. We only have Dashboard
component be protected. Only accessible for loggedIn user):-import React from "react";
import "./styles.css";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import { AuthState } from "./contexts/AuthState";
import ProtectedRoute from "./comps/ProtectedRoute";
import Nav from "./comps/Nav";
import Login from "./comps/Login";
export default function App() {
return (
<AuthState>
<Router>
{/* Nav is an external parent component */}
<Nav>
<Switch>
<Route exact path="/" component={() => "Home page!"} />
<Route exact path="/about" component={() => "About page!"} />
<Route exact path="/login" component={Login} />
<ProtectedRoute
path="/dashboard"
component={() => "Dashboard page!"}
/>
<Route path="*" component={() => "Not Found page!"} />
</Switch>
</Nav>
</Router>
</AuthState>
);
}
Nav
(here we will receive children
as props
for Nav
component - which are actually all our Switch
& Route
from App.js
. In addition, we also do conditional statement
here to only display sidebar for loggedIn user. Else, we'll just display the content (children
we received) of the component
that get rendered):-import React, { useState, useEffect } from "react";
import { NavLink } from "react-router-dom";
import { useAuth } from "../contexts/AuthState";
import { logOut } from "../contexts/AuthAction";
const Nav = ({ children }) => {
const [authState, authDispatch] = useAuth();
const { auth } = authState;
const [isLogout, setIsLogout] = useState(false);
// handle logout
useEffect(() => {
(() => {
if (isLogout) {
logOut(authDispatch);
// reset state
setIsLogout(false);
}
})();
}, [isLogout]);
return (
<>
<ul
style={{
listStyle: "none",
display: "flex",
justifyContent: "center",
alignItems: "center"
}}
>
<li style={{ marginRight: 10 }}>
<NavLink to="/">Home</NavLink>
</li>
<li style={{ marginRight: 10 }}>
<NavLink to="/about">About</NavLink>
</li>
{!auth && (
<li>
<NavLink to="/login">Login</NavLink>
</li>
)}
</ul>
{/* condition happen here
display sidebar for loggedin user
else just display content (children) */}
{auth ? (
// display content with sidebar
<div
style={{
display: "flex"
}}
>
<ul
style={{
listStyle: "none",
margin: 0,
padding: 10,
width: "20%",
minHeight: "100vh",
backgroundColor: "grey"
}}
>
<li style={{ marginBottom: 10 }}>
<NavLink to="/dashboard">Dashboard</NavLink>
</li>
<li>
<button onClick={() => setIsLogout(true)}>Logout</button>
</li>
</ul>
<div
style={{
padding: 10,
width: "100%",
backgroundColor: "lightyellow"
}}
>
<h2 style={{ margin: "0 0 20px 0", padding: 0 }}>Content </h2>
{children}
</div>
</div>
) : (
// just display content without sidebar
children
)}
</>
);
};
export default Nav;
You can refer to this working sandbox of said example use above.
Upvotes: 1