I'm trying to usee getComponent() to implement an loader pattern but the getComponent() is getting called twice for every request made to given route. Is this an expected behaviour (due to bubbling or some other re-rendeinrg of the tree) or is this a bug?
3.0.0
http://jsbin.com/patazecana/1/edit?html,js,console,output
a) Run application
b) Navigate to "down" link
a) on application load only one "getComponent for /" is shown in console
b) on navigation only "getComponent for /" and "getComponentFor /test" are added to console
a) "getComponent for /" is shown twice
b) both are shown twice
No, that's not expected. Perhaps it has something to do with my Promise addition? I don't see anything obvious, but that test case helps!
I seem to have a similar issue as well, but not sure about the getComponent function. In my case with 3.0, all components are rendered more than once upon initial mount, only when I'm using hashHistory.
It seems to be a problem with hashHistory in my case, as changing to browserHistoryresolves the issue.
It's also not an issue with createMemoryHistory ( example : http://jsbin.com/fohemoqibo/1/edit?html,js,console,output ) so it might be related to hashHistory indeed, @kdenz
I think this is the same issue I just asked about on stack. I stuck console logs in my component render functions and noticed that using Router Links renders each component twice. Heres the code that should reproduce this effect:
import ReactDOM from 'react-dom';
import React from 'react';
import { Router, Route, Link, IndexRoute, hashHistory, browserHistory } from 'react-router';
class home extends React.Component {
render(){
console.log('RENDERING HOME');
return(
<Link to='destination'>Link to Destination</Link>
)
}
}
class destination extends React.Component {
render(){
console.log('RENDERING DESTINATION');
return(
<Link to='/'>Link to Home</Link>
)
}
}
var App = React.createClass({
render: function() {
return(
<Router history={hashHistory}>
<Route path='/' component={home}/>
<Route path='destination' component={destination}/>
</Router>
);
},
});
ReactDOM.render(<App />, document.getElementById('app'));
I can confirm that when using browserHistory from react-router, things work as expected, but when using a custom browser history such as using useRouterHistory alongside with createHistory from history, routes get called twice (in my case getComponent is called twice).
Ran into this issue as well (using hash history). It appears that the extra render is triggered by location prop change. location.action is 'PUSH' on initial render, but changes to 'POP' on the second render. In 2.X, location.action is always 'PUSH'
I'm having this same issue I think with react-router-redux, where getComponent is being called twice on initial render.
My setup looks like :
import { Router, Route, browserHistory } from 'react-router'
import { syncHistoryWithStore } from 'react-router-redux'
const history = syncHistoryWithStore(browserHistory, store)
ReactDOM.render(
<Provider store={store}>
<Router history={history}>
<Route path="/" component={App}>
<Route path="foo" component={Foo}/>
</Route>
</Router>
</Provider>,
document.getElementById('mount')
)
And on initial render getComponent is called twice. When switching
const history = browserHistory
getComponent is only called once as expected. Any ideas?
@dadish this is a 3.x issue
I can confirm that this bug is present when using hashHistory.
We're using following:
"react-router": "^3.0.2",
"react-router-redux": "^4.0.6",
Let's not conflate this with react-router-redux. It has a bug right now that's somewhat similar, but unrelated to this.
@timdorr do you have a link to the bug report on react-router-redux and if so how can we determine which bug is which?
I can confirm I'm on:
"react-router": "3.0.2",
"react-router-redux": "4.0.7"
reactjs/react-router-redux#481
This issue should probably be moved to history because from what I can see, it has to do with multiple calls of the history instance's transitionTo method (which, through a chain of events eventually calls getComponent) being triggered by one click. The first time is through the call to history.push and the second is when the HashProtocol's listener is called.
Looks like the problem is the hashchange listener is calling the history listeners directly instead of using transitionTo like 2.x did. While that's fine for the browser history, because popstate only fires on browser-initiated transitions, the hashchange event fires for all mutations of the hash, including the transition itself! That causes it to double up the listener calls.
In any case, as @pshrmn stated, this is ultimately a history issue. I'll open up something over there and link back here.
So if we are using hashHistory how do we prevent this?
I know this issue is ancient, but I want to leave my workaround for those of you who might be working on large, long existing projects (and are stuck on v3)
<Route path='/somewhere' getComponent={ myRoute } />
...
export const myRoute = (location, cb) => {
if (location.location.action === 'POP') {
System.import('somestuff').then((m) => {
// return component here
});
}
};
Most helpful comment
I know this issue is ancient, but I want to leave my workaround for those of you who might be working on large, long existing projects (and are stuck on v3)