In my React Application I need to reload the component when it comes to the path path="/". I know react-router helps us reload easily the current component but I really need this in my application for some styling purpose. In my application I have two paths:
<Route path="/" component={newRoute}/>
and <Route path="/gallery" component={GalleryImages}/>. So, whenever I move from GalleryImages to newRoute I need to reload the newRoute components otherwise the styles are not working. What is the way around here? Here's myApp.js now:
const newRoute = () => {
return (
<div id="colorlib-page">
<div id="container-wrap">
<div id="colorlib-main">
<Introduction/>
<About/>
<Projects/>
<Timeline/>
<Blog/>
</div>
</div>
</div>
)
}
class App extends Component {
render() {
return (
<BrowserRouter>
<div>
<Sidebar/>
<Switch>
<Route path="/" component={newRoute} exact/>
<Route path="/gallery" component={GalleryImages} exact/>
<Route component={Error}/>
</Switch>
</div>
</BrowserRouter>
);
}
}
export default App;
Try to use class component instead of functional component
Related
I have 3 components: Header.js, Main.js, and Footer.js, and App.js is like
const App = () => {
<Header/>
<Main/>
<Footer/>
}
In the Header.js I have links like About and Projects. I would like to be able when I click About in the header for example to display the page About.js in Main.js, and when I click Projects to display the page Projects.js in the Main.js component. I tried to use Routing in the Main.js component like
const Main = () => {
<Router>
<Switch>
<Route exact path='/' component={About.js} />
<Route exact path='/projects' component={Projects.js} />
</Switch>
</Router>
}
but it wouldn't allow me, saying that I cannot use Link outside a router, where I use Link in the Header.js. How can I achieve this?
The Header.js is the following
const Header = () => {
return (
<div>
<ul>
<li>
<Link to="/">
About
</Link>
</li>
<li>
<Link to="/projects">
Projects
</Link>
</li>
</ul>
</div>
)
}
You simply need to make sure your Router component surrounds any components doing routing. For simplicity, here’s the router surrounding your whole app at the App level.
const App = () => {
<Router>
<Header/>
<Main/>
<Footer/>
</Router>
}
Edit: make sure you’re passing your components correctly to the Routes:
const Main = () => {
<Switch>
<Route exact path='/' component={About} />
<Route exact path='/projects' component={Projects} />
</Switch>
}
I have navigation in react and want to redirect to the listing page on click.using this right now which is loading the page
This is my Header.js file
return (
<Link to="/allusers">All Users</Link>
);
This is my App.js file
I imported this
import UsersList from './user/UsersList'; //then i defined
class App extends Component {
render () {
return (
<BrowserRouter>
<div>
<Header />
<Switch>
<Route exact path='/userlist' component={UsersList} />
</Switch>
</div>
</BrowserRouter>
)
}
}
You can check react-router or #reach/router
For example, in #reach/router, you can use the provided Link component to create the same anchor as in your example:
<Link to="/userlist">All Users</Link>
And create a router with all your routes:
<Router primary={false}>
<Home path="/" />
<AllUsers path="/allusers" />
<NotFound default />
</Router>
https://github.com/reach/router
You can play around with this example: https://reach.tech/router/tutorial/04-router
Same thing can be done with react-router.
This achieved through a client side routing: manipulation of the history object of the browser through client side
This is an example rendering a specific component for specific route
import { BrowserRouter, Route, Link, Switch } from "react-router-dom"
<BrowserRouter>
<Switch>
<Route exact path="/" component={HomePage} />
<Route exact path="/allusers" component={AllUsers} />
<Route component={NotFoundPage} />
</Switch>
</BrowserRouter>
// then just pair it up with a navigation bar
<Link to="/">All Users</Link>
<Link to="/allusers">All Users</Link>
These components tied up to a route has access to history object as prop where you can call history.push('/allusers') for other use cases
reference:
https://reacttraining.com/react-router/web/guides/quick-start
You can do that as follows:
goToUserList = () => {
this.props.history.push('/userlist')
}
...
return(
<button onClick={this.goToUserList}>Go User List</button>
)
Hope it helps.
I am using ReactGo boiler-plate to develop an application.
Using react-router for navigating through the site and this is the code,
import { Route, IndexRoute } from 'react-router';
<Route path="/" component={App}>
<IndexRoute component={HomePage} />
<Route path="/login" component={SignIn} pageType="checkout" />
</Route>
and this is the App component,
class App extends Component {
render() {
const rounteProps = this.props.children.props.route;
const pageType = rounteProps.pageType;
return (<div className="app">
{pageType === 'checkout' ? (<CheckoutHeader />) : (<Header />)}
<div className="grid-wrapper site-page content--centered">
<main className="grid grid--space-y site-main">
{this.props.children}
</main>
<Footer />
<Loader />
</div>
</div>);
}
}
I am using pageType for conditional rendering of Header component as there are 2 different headers I have. This works fine with all the routes which do not have any pageType / common pageType.
However when I go to the page /login which has pageType=checkout. It reloads the entire page (and as per my observation it loads the component twice). Don't know why is this happening? Any help would be appreciated. Please let me know if you need any more details.
I am building a small project to test the React Router 4. So far so good, my url updates and my props.locations shows up with withRouter. But I can't seem to change my navBar base on the props.location.
This is what my Routes look like:
<Provider store={ store }>
<BrowserRouter onUpdate={() => window.scrollTo(0, 0)}>
<div className="root">
<App/>
<Switch>
<Route exact path="/" component={HomePageContainer}/>
<Route eact path="/signin" component={SignInContainer}/>
<Route eact path="/reviews" component={Reviews}/>
<Route path="/favorites" component={Favorites}/>
<Route render={() => (
<p>Page Not Found</p>
)}/>
</Switch>
</div>
</BrowserRouter>
</Provider>
My component basically contains my HeaderBar and navBar, I have messages thats in navBar that I want to change so I would have title of the page, My App looks like this:
const App = (props) => {
let toRender = null;
if(props.location.pathname !== '/signin'){
toRender = (
<div>
<HeaderContainer />
<NavBarContainer />
</div>
);
} else {
toRender = null;
}
return(
<div className="App">
{ toRender }
</div>
);
}
I can import my navBar container into each of the routes i have for '/', '/reviews', and '/favorites'. But I don't think that would be a modular way to do it. I also have a shouldComponentUpdate lifecycle method inside NavBar, and I tested with a console.log to print something when it does update when I switch url, but it doesn't. Does anyone have any suggestions on a clean solution to pass in the props to my NavBar without importing it into every single one of the components? I also tried putting App component in the place of Route so I would have:
<App exact path="/" component={HomePageContainer}/>
<Route eact path="/signin" component={SignInContainer}/>
<App eact path="/reviews" component={Reviews}/>
<App path="/favorites" component={Favorites}/>
But then my Components aren't rendering besides the App. I'm not sure what's happening or why it's not rendering the components. Any suggestions would be much appreciate it. Thank you.
Is there a way to nest routes in React Router v4?
This works:
<Router basename='/app'>
<main>
<Route path='/' component={AppBar} />
<Route path='/customers' component={Customers} />
</main>
</Router>
This does not:
<Router basename='/app'>
<Route path='/' component={AppBar}>
<Route path='/customers' component={Customers} />
</Route>
</Router>
Customers Component:
import React, { Component, PropTypes } from 'react'
import styled from 'styled-components'
export default class Customers extends Component {
render () {
return (
<Container>
<h1>Customers</h1>
</Container>
)
}
}
const Container = styled.section`
height: 100%;
padding: 15px;
overflow: auto;
`
Best pattern I have found so far.
// main app
<div>
// not setting a path prop, makes this always render
<Route component={AppShell}/>
<Switch>
<Route exact path="/" component={Login}/>
<Route path="/dashboard" component={AsyncDashboard(userAgent)}/>
<Route component={NoMatch}/>
</Switch>
</div>
I can just keep nesting this inside a component and everything works nice including hmr(If using webpack, dont forget to set output.publicPath to "/")
// dashboard component
<div>
// the same way as before, not setting a path prop
// makes it render on every /dashboard/** request
<Route component={DashboardTAB}/>
<Switch>
// longer path (with same root) than others first
<Route path="/dashboard/graphs/longerpath" component={GraphForm}/>
<Route path="/dashboard/graphs" component={Graphs}/>
<Route path="/dashboard/workers" component={List}/>
<Route path="/dashboard/insert" component={InsertComponent}/>
</Switch>
</div>
I adapted this from the docs, seem to work so far. Probably missing something obvious, and yes it is not the v4 way but we need all the routes defined in one place.
function RouteNest(props){ return (
<Route exact={props.exact} path={props.path} render={ p => <props.component {...p} children={props.children}/> } />
)}
export const MainRoutes = props =>
<div className='content layout'>
<Route exact path="/" component={Landing}/>
<Route path={'/contact'} component={Contact}/>
<RouteNest path={'/thing'} component={CompoWithSub}>
<RouteNest path={'/thing/suba'} component={SubComponentA}/>
<RouteNest path={'/thing/subb'} component={SubComponentB}/>
</RouteNest>
</div>
export const CompoWithSub = props => <div>{props.children)</div>
You're AppBar component is in charge of rendering Customers. For customers to be called, you have to render the children of AppBar. Anything directly nested under AppBar is a child of AppBar.
import React from 'react';
const AppBar = ({ children }) => (
<div>
<header>
<h1> stuff </h1>
</header>
{children}
</div>
);
export default AppBar
Please note that only AppBar will render when you visit "/". AppBar and Customers will render when you visit "/customers".
If someone wants to have nested routes without typing prefix of wrapper route I've created something like this in TSX:
Imports:
import * as React from 'react';
import { Route, RouteComponentProps, RouteProps, Switch } from 'react-router-dom';
import Index from 'views/index';
import Login from 'views/login';
import NoMatch from 'views/no-match';
Interfaces:
interface INestedRoutes {
nested?: string;
}
interface INestedRoute extends RouteProps, INestedRoutes {}
NestedRoute and NestedRoutes wrapper:
class NestedRoutes extends React.Component<INestedRoutes> {
public render() {
const childrenWithProps = React.Children.map(this.props.children, (child) => {
return React.cloneElement(
child as React.ReactElement<any>, { nested: this.props.nested },
);
})
return childrenWithProps;
}
}
const NestedRoute: React.SFC<INestedRoute> = (props: INestedRoute) => {
return <Route path={`${props.nested}${props.path}`} component={props.component} />;
};
And routes with wrapper:
const MultiLanguage: React.SFC<RouteComponentProps<any>> = (props: RouteComponentProps<any>) => {
return (
<NestedRoutes nested={props.match.path} >
<NestedRoute path="/test" component={Login} />
<NestedRoute path="/no-match" component={NoMatch} />
</NestedRoutes>
);
};
export default (
<Switch>
<Route path="/:language" component={MultiLanguage}/>
<Route exact={true} path="/" component={Index} />
<Route path="/login" component={Login} />
<Route component={NoMatch} />
</Switch>
);
For nested routes there is a very simple way which i using.
Example main router is be like that
<Router history={history}>
<Switch >
<Route path="/" component={Home}></Route>
</Switch>
</Router>
Inside Home component using Nested Routing be like:
<div className="App">
<Navbar title="Home" links = { NavbarLinks }/>
{this.renderContentPage()}
</div>
renderContentPage will check the URL and render the nested route.
<Route exact path="/" component={Page1}></Route>
<Route exact path="/page1" component={Page1}></Route>
<Route exact path='/page2' component={Page2} />
So inside Home component page1 and page2 components rendered.
Route expects a single children i.e. a component.
It should not be a new Route.
What you can do is to include your nested routes inside your customers component.
Also make sure to remove exact inside the routes in customers component.