Can't seem to figure out what's wrong even browsing through a couple of examples of react-router-dom...
So here's my main page:
class MyPage extends Component {
render () {
return (
<Aux>
<NavigationHeader />
<Switch>
<Route path="/me" exact component={PersonalInfoContainer}/>
<Route path="/exps" component={ExpsContainer}/>
</Switch>
{/* <ExpsContainer /> */}
</Aux>
);
}
I want to create a page to show some personal info of the user as the /me page. So here's the PersonalInfoContainer:
class PersonalInfoContainer extends Component {
componentDidMount () {
console.log("PI container: ", this.props);
}
render () {
return (
<Aux>
<Link to={this.props.match.url + '/edit' }>EDIT</Link>
<Switch>
<Route path={this.props.match.url + '/edit'} component={PersonalInfoForm}/>
<Route path={this.props.match.url} component={PersonalInfoDetail}/>
</Switch>
</Aux>
)
}
}
Here's the problem, what I want to do is have an EDIT button that leads to an input form to let users patch their info. I assume with this setup, the link should be /me/edit, but no matter I use Link to={this.props.match.url + '/edit' } or Link to={'/edit' } (which in this case the url is simply /edit), it always returns a blank page. I have tested that form component to be working so it really should be something wrong with my routing method.
Thanks for any help.
Related
I have a router which has a link to a product details page, problem is, the application is being displayed in a android webview so ... if am viewing a product details page and clicked back, the whole application will exit.
is there a way to make the use go back to the home page ? or I have to implement a back button ?
class App extends React.Component {
render() {
return (
<div>
<Router>
<Switch>
{/* <PrivateRoute exact path="/" component={HomePage} /> */}
<Route exact path="/" component={Home} />
<Template>
<Route path="/:id" component={PropertyTemplate} />
</Template>
</Switch>
</Router>
</div>)
}
}
It's not neccessary to implement backbutton - just this code make work:
history.goBack()
Here is implemented BackButton - just add this in common folder in architecture & reuse.
import React from 'react';
import { withRouter } from 'react-router-dom';
import ReturnIcon from '../../img/tech/return-white-icon.svg'
const GoBack = ({ history }) => <img src={ReturnIcon} onClick={() => history.goBack()} alt="Go back" />;
export default withRouter(GoBack);
I'm trying to figure out how to change the state of my Dashboard when a new route is clicked. This new route change needs to update the TopMenu component.
This is the code for the Dashboard
class Dashboard extends Component {
constructor (props) {
super(props)
this.state = {
selectedMenuItem: 'Now'
}
}
render () {
return (
<Router>
<div id='dashboard-container'>
<LeftMenu/>
<div className='column'>
<TopMenu selectedMenuItem={this.state.selectedMenuItem} />
<div id='content-container'>
<div>
<Switch>
<Route exact path='/' component={Now} />
<Route exact path='/surveys' component={Surveys} />
<Route exact path='/my-questions' />
<Route exact path='/feedback' />
<Route exact path='/logout' />
<Route render={function () {
return <p>Not Found</p>
}} />
</Switch>
</div>
</div>
</div>
</div>
</Router>
)}}
This is the code for the TopMenu
class TopMenu extends Component {
render () {
return (
<h3>{this.props.selectedMenuItem}</h3>
)
}
}
How do I listen to a change in React Router such that I can change the 'selectedMenuItem' state variable in the Dashboard and pass that to TopMenu.
Thanks!
Assuming you are using version 4, check the usage of match in React Router 4: https://reacttraining.com/react-router/web/api/match
match will include all the path information you will need to handle route changes. You can access it by calling this.props.match in your top level page component.
I had the same problem and I solved it with withRouter which is build for integrate router with redux, the only thing you need to do is wrap your connect with withRouter. for more information read redux integration document
I have a React app that has a basic structure like seen below. I am attempting to programmatically redirect the user to /profile route but I am seeing Warning: You tried to redirect to the same route you're currently on: "/profile".
Inside the Main component header I have a form that should redirect the user to /profile. The only way that I was able to get this working is to add && this.props.location.pathname !== '/profile' to the state.toProfile condition. This feels a bit dirty. It seems like there is a better way.
I am taking the approach recommended in this blog post https://tylermcginnis.com/react-router-programmatically-navigate/, it seems like this doesn't work if the route you redirect to contains the same component as the route that was redirected from.
class App extends Component {
render() {
return (
<BrowserRouter>
<Switch>
<Route path="/dashboard" component={Dashboard} />
<Route component={Main} />
</Switch>
</BrowserRouter>
);
}
}
class Main extends Component {
state = {
toProfile: false
}
render() {
if (this.state.toProfile === true) {
return <Redirect to='/profile' />
}
return (
<header>
...
</header>
);
}
}
you need to add a route for /profile, atm profile goes to Main that goes to /profile... again
I'm building an article search with React [15.6.1] and Router [4.1.1] and noticed that when trying to access an article directly the previous component is loaded, even thou it's not the one that's being called
// === Layout ==================
class Layout extends React.Component {
render() {
return (
<Provider store={this.props.store}>
<HashRouter>
<div>
<Switch>
<Route exact path="/" component={SearchFilter} />
<Route path="/article/:guid" component={Article} />
</Switch>
</div>
</HashRouter>
</Provider>
);
}
}
// === SearchFilter ==================
class SearchFilter extends React.Component {
componentDidMount() {
console.log('SearchFilter Did Mount');
}
render() {
return (
<div>...</div>
);
}
}
// === Article ==================
class Article extends React.Component {
componentDidMount() {
console.log('Article Did Mount');
}
render() {
return (
<div>...</div>
);
}
}
So when going to the root localhost:3000/#/ it prints
// SearchFilter Did Mount
And when I access an article directly like this localhost:3000/#/article/123456 it prints
// SearchFilter Did Mount
// Article Did Mount
So my question is, how can I prevent it from running the previous route?
Because I would like to dispatch some actions there that would trigger some ajax calls to the webservice.
Thanks
Try this instead :
<HashRouter basename="/">
<div>
<Switch>
<Route exact path="/search" component={SearchFilter} />
<Route path="/article/:guid" component={Article} />
</Switch>
</div>
</HashRouter>
Edit:
For me its working well... So like said... there is something really weird and hidden happening on your machine, or you just put / and then rewrite url to /#/article/123 and it cause the first log stays in the console, but its from the previsous url "/" and if you reload the browser by F5 on the new url /#/article/123 you will see only the "Article did mount"
I have a react multi step form with a flux store like this:
// MultiForm.js
....
import LoadFile from './components/LoadFile';
import LoadPeople from './components/LoadPeople';
import Confirmation from './components/Confirmation';
class MultiForm extends Component {
.
.
.
nextPage() {
// Update page number with a flux action
MultiStepActions.nextPage();
}
previousPage() {
// Update page number with a flux action
MultiStepActions.previousPage();
}
render() {
const {pagina} = this.state;
<div className="container">
{page === 1 && <LoadFile
handleChange={this.handleChange}
file={this.state.file}
nextPage={this.nextPage}
data1={this.state.data1}
data2={this.state.data2}
data3={this.state.data3}/>
}
{page === 2 && <LoadPeople
listPeople={this.state.listPeople}
nextPage={this.nextPage}
previousPage={this.previousPage}
handleChangePeople={this.handleChangePeople}/>
}
{page === 3 && <Confirmation
listData={this.state.listData}
nextPage={this.nextPage}
previousPage={this.previousPage}/>
}
</div>
}
}
// Index.js with react-router
import Menu from './components/Menu';
class Index extends Component {
class App extends Component {
render() {
return (
<div>
<Menu />
{this.props.children}
</div>
)
}
}
render((
<Router history={browserHistory}>
<Route path="/" component={App}>
<Route path="/MultiForm" component={MultiForm}>
</Route>
</Route>
</Router>
), document.getElementById('app'));
}
It is a summary of the main component (MultiForm) and a basic react router scenario.
In the component I am using a flux store to set and get the actual number of page of the multi step form and then render the component according to the actual page.
In the components (LoadFile, LoadPeople, Confirmation) I have a button to navigate to the next and previos page (via nextPage and previousPage functions) and all wokr ok.
Now I want achieve the same result using the back and previous buttons of the browser and I suppose with react-router. So, how I must configure react router or what I need to do in order to getting the browser buttons to work equals to my next and previous buttons?
You cannot override a browser's navigation buttons. You can however, hook up the pages states defined in react-router, and as the user browses around using the navigation buttons, your application state remains synced to the browser state.
What i would suggest for you here is to create a parameter for your MultiForm route:
<Route path="/Multiform/:page" component={MultiForm} />
This would then allow you to get that page parameter in this.props.params.page
Even better, you can hook up each of the child components as routes in themselves:
<Route path="/Multiform/" component={MultiForm}>
<Route path="1" component={LoadFile} />
<Route path="2" component={LoadPeople} />
<Route path="3" component={Confirmation} />
</Route>
class Multiform extends Component {
//...
render() {
return (
<div className="container">
{ this.props.children }
</div>
)
}
}