-
Notifications
You must be signed in to change notification settings - Fork 641
Getting You cannot change <Router routes>; it will be ignored
when hot-loading
#179
Comments
+1 Same issue. |
This sounds like a react-router issue. Please file there; re-open this if I'm wrong. |
+1 same here. reproduced by doing this:
|
Started to get the same error. |
Hi, |
I found solution for my problem. |
hi @amertak I have the same issue. I can't see what you're talking about. Can you explain with some code snippet please ? Best regards |
Hi @lauterry I'll try.
My problem was, that all the containers (
Also all other components in app were using I have to point out that this might not be the same issue as you have. |
Hi all, Same happened here and the solution was declaring the routes object outside of the render method as PlainRoutes, so it doesn't get updated. So taking @tomasz-szymanek code it would be something like: const routes = {
path: '/',
component: App,
childRoutes: [
{ path: '/about', component: About },
{
path: '/posts',
component: Posts,
childRoutes: [ { path: '/post/:nr', component: Post } ]
},
{ path: '*', component: NoMatch}
]
};
const renderAll = () => {
ReactDOM.render(
(
<Provider store={store}>
<Router history={browserHistory} routes={routes} />
</Provider>
), document.getElementById('root')
);
};
store.subscribe(renderAll);
renderAll(); That way the routes list is not changed every time renderAll is executed and react-router doesn't complain. |
thanks @OriolBonjoch it works for me! |
You are god to me @OriolBonjoch |
The PlainRoutes approach suggested by @OriolBonjoch didn't work for me. Is there an actual working example of react-router-redux with hot reloading? |
First of all that is a warning that doesn't stop anything, its just annoying. I think this happens because of react-redux top level Provider component. It triggers the componentWillReceiveProps in Route component even when they haven't really changed (component and path remains the same but is a new object since you created it inside render function). Besides that I'm curious, @Kitanotori in what case you modified the routes in runtime? |
@OriolBonjoch It stops the hot reloading. The changes I make to the route components are not being hot reloaded. I will post an example app to Github soon in order to explain the issue better. |
@OriolBonjoch It seems that I somehow got it working in the example I built. I wonder what I did differently in my main project... Have to examine further. Here is an example of how to set up React, Redux, Saga, and routing together with Webpack, Babel, and hot reloading: https://github.com/Kitanotori/react-webpack-babel-hotreload-example |
@Kitanotori I think the reason your approach worked is because you extracted the routes into a module, so they were only declared once, instead of recreating them with every render. I wasn't using react-router-redux, but I did have some state in my Root component for growl-style notifications, and I was getting this "cannot change Router..." warning whenever Root re-rendered. I was able to get the warning to go away by extracting my routes. Before: class Root extends Component {
render() {
return (
<Router history={browserHistory} createElement={this.createElement}>
<Route component={App}>
<Route path="/" component={MainPage}/>
<Route path="/page2" component={Page2}/>
<Route path="/settings" component={SettingsPage}/>
</Route>
</Router>
)
}
} After: const routes = (
<Route component={App}>
<Route path="/" component={MainPage}/>
<Route path="/page2" component={Page2}/>
<Route path="/settings" component={SettingsPage}/>
</Route>
);
class Root extends Component {
render() {
return (
<Router history={browserHistory} createElement={this.createElement}>
{routes}
</Router>
)
}
} |
In my case the bug was the forceUpdate method called by subscribing to the redux store... |
In my case, the issue seems to occur when passing props to the routes. When the props change, the warning is fired.
I don't know how to get around this. Any ideas? |
I had this problem too and it turned out it was due to the same thing as @amertak had. I had a base component which all my other components inherited, so every change caused HMR to propagate up to route definitions and then subsequently the root component. Bizarre. |
@jeznag those properties are for Route component (like history or children)? If its not like that I would add it in ChooseCourseComponent and DoCourseComponent connect props. |
@OriolBonjoch yeah good point. I ended up doing that :) Misunderstood redux and thought I could only have one connected component. |
in case it helps anyone else, here is my code: // app.js
...
const store = createStore(),
routes = createRoutes(store);
ReactDOM.render(
<Provider store={store}>
<Router history={hashHistory}>
{routes}
</Router>
</Provider>,
document.getElementById('react-root')
);
// routes.js
...
export function create(store) {
...
return (
<Route>
<IndexRoute component={InitPage} />
<Route path="/editor" component={EditorPage}/>
<Route path="*" component={InitPage}/>
</Route>
);
} Ensure your components inherit directly from |
I am unable to get this working with getComponent. I'm trying to code split my app by routes using System.import and Webpack 2. Although I am unable to get code splitting working using any method for some reason, hot reload does not work when using both getComponent and Provider: App.js:
Root:
routes.js:
index routes.js:
Container.jsx:
|
@DragonFire353 Why do you repeat the render in the reload hook? if (module.hot)
module.hot.accept('./Root', () => {
render(
<AppContainer>
<Root store={store} history={history} />
</AppContainer>, mountNode);
}); |
@hiddentao because that's what was in the example for hot loader 3: https://github.com/gaearon/redux-devtools/blob/64f58b7010a1b2a71ad16716eb37ac1031f93915/examples/todomvc/index.js |
hmmm it works if I make Root an actual React Component:
Not sure why there'd be a difference with this when it was working without Provider. Still get the warning though. And code splitting doesn't work but that's a separate issue... |
thanks! |
I'm getting the error Warning: [react-router] You cannot change ; it will be ignored index.js
root.js
routes.js
webpack.dev.config
app.js
|
@adrianmcli Thanks, that simplifies things a ton. But reading the react-hot-loader docs for version 3 states the following: AppContainer is a component that handles module reloading, as well as error handling. The root component of your app should be nested in AppContainer as a child. When in production, AppContainer is automatically disabled, and simply returns its children. React Hot Loader 3 does not hide the hot module replacement API, so the following needs to be added below wherever you call ReactDOM.render in your app:
https://github.com/gaearon/react-hot-loader/tree/next/docs |
@wonbyte I'm not using version 3 of React Hot Loader. I'm using the latest stable version from NPM, which is 1.3.1. It's been stable and battle-tested for a long long time. Version 3 has been "on the horizon" for almost a year now. I'm not holding my breath until they come out with an actual npm release. What I would recommend is that you try to get everything working with 1.3.1 (the latest stable version). And then incrementally migrate to 3.0 with the supplied guide. |
How to pass props to route. I am doing this but still getting the error
|
Same issue hits me. @dceddia 's solution saved my day. |
adding the
|
Thanks @chotalia! That works for me. |
@chotalia your solution is not good and has side effect, obviously it changes all components states to their default states. |
Adding a class Routes extends Component {
shouldComponentUpdate () {
return false
}
render () {
return (
<Router>
//....
</Router>
)
}
} Then rendering that in my Root component |
@LumberJ mind sharing the source code? I tried that approach without success; You sure the warning message stopped showing? |
@heldrida the entire thing looks something like this: (leaving out details like setting up history and the redux store) // App.jsx
import {Router, Route, IndexRoute} from 'react-router'
const App = ({children}) => (
<div className='app-container'>
{children}
</div>
)
class Routes extends Component {
shouldComponentUpdate () {
return false
}
render () {
return (
<Router history={this.props.history}>
<Route path='/' component={App}>
<IndexRoute component={App} />
</Route>
</Router>
)
}
}
class Root extends Component {
render () {
const {store, history} = this.props
return (
<Provider store={store}>
<Routes history={history} />
</Provider>
)
}
} // index.jsx
import { AppContainer } from 'react-hot-loader'
ReactDOM.render(
<AppContainer>
<App store={store} history={history} />
</AppContainer>,
document.getElementById('root')
)
// Hot Module Replacement API
if (module.hot) {
module.hot.accept('./App', () => {
const NextApp = require('./App').default
ReactDOM.render(
<AppContainer>
<NextApp store={store} history={history} />
</AppContainer>,
document.getElementById('root')
)
})
} |
Here's what worked for me: // Render the application.
render(
<Provider store={store}>
{router(history)}
</Provider>,
document.getElementById('app')
);
// Support for hot reloading.
if (module.hot) {
import('react-hot-loader').then(({ AppContainer }) => {
module.hot.accept('./router', () => {
import('./router')
.then((routerModule) => {
render(
<AppContainer>
<Provider store={store}>
{routerModule.default(history)}
</Provider>
</AppContainer>,
document.getElementById('app')
);
});
});
});
} |
@LumberJ Thanks man, this worked for me too. Wonder what's the logic behind this? |
,*
…On Mar 20, 2017 2:47 PM, "arshmakker" ***@***.***> wrote:
@LumberJ <https://github.com/lumberj> Thanks man, this worked for me too.
Wonder what's the logic behind this?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#179 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AHd3GlAlkSP0WneBERldmcZFODbfiZHGks5rnnV6gaJpZM4HBnpo>
.
|
Here is the solution which worked in my case: import * as React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import {AppContainer} from 'react-hot-loader';
import createHistory from "history/createBrowserHistory";
const history = createHistory();
const root = document.getElementById('root');
const render = (Component, props = {}) => {
ReactDOM.render(
<AppContainer>
<Component {...props}/>
</AppContainer>,
root
);
}
render(App, { history });
// Hot Module Replacement API
if (module.hot) {
module.hot.accept('./App', () => {
render(App, { history });
});
} How it was before: import * as React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import {AppContainer} from 'react-hot-loader';
const render = (Component, props = {}) => {
ReactDOM.render(
<AppContainer>
<Component/>
</AppContainer>,
document.getElementById('root')
);
}
render(App);
// Hot Module Replacement API
if (module.hot) {
module.hot.accept('./App', () => {
render(App);
});
} However, as you see - main thing is to put history declaration out of the As this repository is moving into the main |
Hi, @PavelPolyakov i found an interesting problem with the working code you provided. if i add react-hot-loader/babel plugin in .babelrc as the documentation shows
then, i will still see the warning message. i am using "[email protected]". The warning message goes away when removing that plugin. Can anyone help to explain why? Thanks |
I also encountered this problem in my project , but I find my react-router vision is 2.xxx , then I browsed the docs Migrating from v2/v3 to v4 , and I migrating the version to 4.x , this problem never happen . it shows : The v4 component is actually a component. so wherever you render a component, content will be rendered. When the 's path matches the current location, it will use its rendering prop (component, render, or children) to render. When the 's path does not match, it will render null. |
Squashed changes needed to make this happen * Separate routes to a separate file and add key to App. reactjs/react-router-redux#179 * Add react-hot-loader boilerplates to app. * Add node-sass, react-hot-loader to webpack config.
call ReactDOM.unmountComponentAtNode. it will work! ReactDOM.render((
<Provider store={store}>
<Router routes={routes} history={history} />
</Provider>
), document.getElementById('app'));
if (module.hot) {
module.hot.accept('./routes', () => {
ReactDOM.unmountComponentAtNode(document.getElementById('app'));
const nextRoutes = require('./routes').default;
ReactDOM.render(
<Provider store={store}>
<Router routes={nextRoutes} history={history} />
</Provider>,
document.getElementById('app'),
);
});
} |
When hot-loading I am getting the warning:
My process is I save a file in view with some update like I added a
<span>
, and it shows up on the page, but then this error shows. I checked into it, finding the commit here: remix-run/react-router@62f6ef2I don't know what this does. It looks like it's saying if you're on the current page and the route doesn't change, but everything else stayed the same, then warn.
The text was updated successfully, but these errors were encountered: