ReactJS Routing Page Refresh - javascript

Currently using ReactJS to construct a small web app. I have the following parent function:
const Main = () => {
return (
<div className="dialog-base">
<BrowserRouter>
<Switch>
<Route exact path="/login" component={Login}></Route>
<Route exact path="/login/forgot_password" component={ForgotPwd}></Route>
<Route exact path="/login/reset_password/:key" component={ResetPwd}></Route>
<Route exact path="/portal" component={Portal}></Route>
</Switch>
</BrowserRouter>
</div>
);
}
and the following is the "Portal" component:
class Portal extends React.Component {
render = () => {
return (
<BrowserRouter basename="/main">
<div className="navmenu">
<NavLink to="messaging" activeClassName="selected">Messaging</NavLink>
<NavLink to="files" activeClassName="selected"></NavLink>
<NavLink to="payledger" activeClassName="selected"></NavLink>
</div>
<div className="apparea">
<Switch>
<Route path="/messaging" component={Messaging}></Route>
<Route path="/files" component={Files}></Route>
<Route path="/payledger" component={PayLedger}></Route>
</Switch>
</div>
</BrowserRouter>
);
}
}
When the portal component is loaded and I refresh the web page, the page goes blank. I am assuming that this has something to do with the nested routing? Any help on how to fix it would be much appreciated.

You don't need two <BrowserRouter />. Just define one <BrowserRouter /> in your top level component.
In react-router-dom v4+ the <Route /> is just like a regular component and you can use it inside your components to render UI when the path matches the URL.
Here is the working codesandbox example.
Make sure not to put exact on your parent <Route /> because when you have child routes like /main/messaging the <Route exact path="/main" /> never gets to render and therefore children of that route can't be rendered also.
You keep your <Main /> component as is but remove the exact from the <Route path='/portal' /> and change the <Portal />.
class Portal extends React.Component {
render = () => {
return (
<React.Fragment>
<div className="navmenu">
<NavLink to="/portal/messaging" activeClassName="selected">Messaging</NavLink>
<NavLink to="/portal/files" activeClassName="selected"></NavLink>
<NavLink to="/portal/payledger" activeClassName="selected"></NavLink>
</div>
<div className="apparea">
<Switch>
<Route path="/portal/messaging" component={Messaging}></Route>
<Route path="/portal/files" component={Files}></Route>
<Route path="/portal/payledger" component={PayLedger}></Route>
</Switch>
</div>
</React.Fragment>
);
}
}

Related

How to remove a site header from specific pages React

I have set up a login page for my web app but the site header component I created earlier appears on the top. It has a menu in it that leads to other pages, so if it's on the login page a user doesn't need to login when they can just click the menu option that will lead them to the home page.
I would like the site header to be invisible on the login, register and reset pages.
index.js
return (
<BrowserRouter>
<SiteHeader />
<Routes>
<Route path="/reviews/:id" element={ <MovieReviewPage /> } />
<Route path="/movies/home" element={<HomePage />} />
<Route path="/movies/favorites" element={<FavoriteMoviesPage />} />
<Route path="/movies/upcoming" element={<UpcomingMoviesPage />} />
<Route path="/movies/:id" element={<MoviePage />} />
<Route exact path="/" element={<LoginPage />} />
<Route exact path="/register" element={<RegisterPage />} />
<Route exact path="/reset" element={<ResetPage />} />
<Route path="*" element={ <Navigate to="/" /> } />
</Routes>
</BrowserRouter>
);
};
There are many ways to do that, but personally, I prefer to do so.
export const MyLayout = ({children}) => {
return (
<>
<SiteHeader />
{children}
</>
)
}
And after all, put your PageComponent inside component wherever you need.
For example.
const HomePage = () => {
return (
<MyLayout>
<div> This is Home Page </div>
</MyLayout>
)
}
Add an Authentication Context Provider. You could then read the context and render the header when you're logged in, else not.
https://codesandbox.io/embed/authentication-with-react-context-d3x0r

Why are my React components rendering in all routes?

This is the my App() function in App.js, the comps :"Sidebar, Feed and Widgets" keeps rendering in route ="/" and also ="/login" as well, in addition to that "Login" comp didn't even render in route ="/login".
<Router>
<div className="app">
<Switch>
<Route path="/">
<Sidebar />
<Feed />
<Widgets />
</Route>
<Route path="/login">
<Login />
</Route>
</Switch>
</div>
</Router>
If you are using the latest version of react-router-dom, you must change the Switch to Routes
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import { Sidebar, Feed, Widgets } from '...'
const Home = () => {
return (
<Sidebar />
<Feed />
<Widgets />
)
}
const App = () => {
return (
<Router>
<div className="app">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
</Routes>
</div>
</Router>
)
}
You need to add exact with "/'" route.
In your case when you are not adding exact, React router will match '/login' path with the first path '/' and will render accordingly without checking next routes. By adding exact, first '/' will not match and it will match with second route '/login'.
<Router>
<div className="app">
<Switch>
<Route path="/" exact>
<Sidebar />
<Feed />
<Widgets />
</Route>
<Route path="/login">
<Login />
</Route>
</Switch>
</div>
</Router>
For more information, you can also refer this similar question: React : difference between <Route exact path="/" /> and <Route path="/" />
The Switch component exclusively matches and renders routes, so only 1 route can ever be matched. You've an issue with the order of your routes though, so only the "/" path matches since it's earlier and is rendered. The route for "/login" can never be reached, as-is.
In other words, this means is that when the path is "/login" that "/" still matches it and is the route rendered. In react-router-dom v5 think of the path props as a "path prefix".
In the Switch component, path order and specificity matter! You should order the paths from more specific to less specific. This allows more specific paths like "/login" to be matched before trying the less specific paths.
<Router>
<div className="app">
<Switch>
<Route path="/login">
<Login />
</Route>
<Route path="/">
<Sidebar />
<Feed />
<Widgets />
</Route>
</Switch>
</div>
</Router>

Render components under root route not working as expected

I have a route path / that rendering Home component
Home component contain a list. every item should render a route /:id
So much paths will be www.example/:id
I would render lists content under home content.
My problem is that every time I click on a list item the list get disappeared and nothing is rendered.
function Home() {
return (
<div>
<h1>Topics</h1>
<ul>
{topics.map(({ name, id }) => (
<li key={id}>
<Link to={`/${id}`}>{name}</Link>
</li>
))}
</ul>
<hr />
<Route path={`/:topicId`} component={Topic} />
</div>
);
}
function Topic() {
return <div>TOPIC</div>;
}
class App extends React.Component {
render() {
return (
<Router>
<Route exact path="/" component={Home} />
</Router>
);
}
}
export default App;
Here's an example
For this kind of similar routes. we will deal with exact props. No need to reorder the routes.
<Switch>
<Route exact path="/" component={Home} />
<Route path="/:topicId" component={Topic} />
<Switch>
For more details, you can follow https://reactrouter.com/web/api/Route/exact-bool
You should remove the exact, like so:
<Router>
<Route path="/" component={Home} />
<Route path="/:topicId" component={Topic} />
</Router>
Now your Home & Topic will appear

React-Router-DOM: unable to render Link in the same page (component)

consider the following example, I have a login page and an admin page. After logging in we will be redirected to admin page.
The admin page is shown as follows.
Desired behaviour: To render cars component in the admin component itself
Actual behaviour: On clicking cars or bikes component they are being rendered on a different page.
code is as follows
App.js
//imports here
function App() {
return(
<Router>
<Switch>
<Route exact path="/" component={Login} />
<Route exact path="/admin" component={Admin} />
<Route exact path="/cars" component={Cars} />
<Route exact path="/bikes" component={Bikes} />
</Switch>
</Router>
);
}
Admin.js
//imports here
const Admin = () => {
return (
<Fragment>
<div className="is-flex">
<Sidebar />
<Navbar />
</div>
</Fragment>
);
};
navbar.js
// imports here
const Sidebar = () => {
return (
<aside className="aside">
<p className="menu-label">Test Routes</p>
<ul className="menu-list">
<li>
<Link to="/cars">Cars</Link>
</li>
<li>
<Link to="/bikes">Bikes</Link>
</li>
</ul>
</aside>
);
};
Using react-router-dom ^5.1.2
Tried this but not able to understand what I missed? how to solve this problem?
Move your default route to the bottom of the stack. i.e.
function App() {
return(
<Router>
<Switch>
<Route path="/admin" component={Admin} />
<Route path="/cars" component={Cars} />
<Route path="/bikes" component={Bikes} />
<Route exact path="/" component={Login} />
</Switch>
</Router>
);
}

Unable to render react components upon clicking the Links

I have a react application in which I have wrapped layout components for the other routes, the thing is when I click the links present in the sidebar(part of layout) they are not being rendered on the screen, here is my code.
App.js
//Imports here
<Provider store={store}>
<Router>
<Switch>
<Layout>
<Route exact path="/admin" render={() => <Admin />} />
<Route exact path="/employees" render={() => <Employees />} />
<Route exact path="/profile" component={Profile} />
</Layout>
<Switch>
</Router>
</Provider>
Layout.js
//imports here
//styling here
<Link to='/employees' />
// and likewise for rest of the routes
When clicking the links ie, employees or profile they aren't being rendered, tried console.log to see if my layout was obstructing that, but no use. Please help me
It should be inside the Switch component but you can wrap it with a Layout component like that.
const Headers = () => (
<Layout>
<ul>
<li>
<Link to="/admin">Admin</Link>
</li>
<li>
<Link to="/profile">Profile</Link>
</li>
<li>
<Link to="/employees">Employees</Link>
</li>
</ul>
</Layout>
);
function App() {
return (
<Router>
<Layout>
<Header></Header>
<Switch>
<Route exact path="/admin" render={() => <Admin />} />
<Route exact path="/employees" render={() => <Employees/>}/>
<Route exact path="/profile" component={Profile} />
</Switch>
</Layout>
</Router>
);
}
If your URL is changing but the content is not being rendered, the problem is this, apart from wrapping the Routes as mentioned in #G.aziz 's answer since the routes are children WRT layout components we have to use {props.children} inside the layout component to render the content like so...
Layout.jsx
<div>
<Sidebar />
<Navbar />
{props.children} // here we are rendering the routes which we mentioned in the switch component in App.js
</div>
For me this solution fixed. Also please refer this question for further information. React-router v4, URL changing but component doesn't render

Categories

Resources