-->

react-route,react-hot-loader.webpack (You cannot c

2019-03-24 22:21发布

问题:

it's my first project that use react,react-router,react-hot-loader,webpack-dev-server and webpack. when I change the code in react component, the hot-loader become effective, but at the same time, the console tell me a warning:

You cannot change 《Router routes》; it will be ignored.

I don't know how to solve this issue.there is code:

webpack code:

    var path = require('path');
    var webpack = require('webpack');

    module.exports = {
      devtool: 'source-map' ,
      entry: [
        'webpack-dev-server/client?http://localhost:3000',
        'webpack/hot/only-dev-server',
        './jsx/index'
      ],
      output: {
        path: path.join(__dirname, 'public'),
        filename: 'bundle.js',
        publicPath: '/public/'
      },
      plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoErrorsPlugin()
      ],
      resolve: {
        extensions: ['', '.js', '.jsx', 'json']
      },
      module: {
        loaders: [{
          test: /\.js$/,
          exclude: /node_modules/,   
          loaders: ['react-hot', 'babel'],
          }]
      },
      watch:true
    };

index code:

    import React from 'react'
    import ReactDOM  from 'react-dom'
    import { Router, Route, Link } from 'react-router'
    import App from './index/app'
    import About from './index/about'
    import Inbox from './index/inbox'
    class Routers extends React.Component {
      render() {
         return ( 
            <Router>
                <Route path="/" component={App}>
                  <Route path="about" component={About} />
                  <Route path="inbox" component={Inbox} />
                </Route>
            </Router>
          );
        }
    }

ReactDOM.render(<Routers />, document.getElementById('root'));

thank you !!!!

回答1:

Only thing you need to do, it's to throw <Route /> out of render() method.
So, there are many ways to solve this issue.
Most Official way is what @Stormy say.
My solution like this:

const routes = (
  <Route path="/" component={App}>
    <Route path="about" component={About} />
    <Route path="inbox" component={Inbox} />
  </Route>
)

// Don't let <Route> in render() method
class Routers extends React.Component {
  render() {
     return ( 
        <Router>
          { routes }
        </Router>
      );
    }
}


回答2:

Try to use this configuration https://github.com/reactjs/react-router/issues/2704#issuecomment-170940448

  const routeConfig = [
  { path: '/:locale',
    component: App,
    indexRoute: { component: NewsCardsContainer },
    ...
  }
];
return (
  <IntlProvider key="intl" {...intlData}>
    <Router history={history} routes={routeConfig} />
  </IntlProvider>
)


回答3:

Stormy's suggestion of using <Router routes={Routes}/> worked for me. Here are my warning free code snippits with react hot module replacement:

./index.js

import './globals';
import React from "react";
import ReactDOM from "react-dom";
import { AppContainer as HotContainer } from "react-hot-loader";
import { browserHistory } from 'react-router';
import Routes from "./components/Routes.jsx";

const render = function() {
    let Router = require('react-router').Router;
    ReactDOM.render(
        <HotContainer>
            <Router history={browserHistory} routes={Routes}/>
        </HotContainer>,
        document.getElementById('react-container'),
    );
};

render();

if( module.hot ) {
    module.hot.accept('./components/Routes', () => {
        render();
    });
}

./components/Routes.jsx

import React from "react";
import { Route, IndexRoute } from "react-router";
import App from "./App.jsx";
import Graphs from "./graphs/Graphs.jsx";
import Trends from "./trends/Trends.jsx";
import Patterns from "./patterns/Patterns.jsx";

const Routes = (
    <Route path="/" component={App}>
        <IndexRoute component={Graphs}/>
        <Route path="graphs" component={Graphs}/>
        <Route path="trends" component={Trends}/>
        <Route path="patterns" component={Patterns}/>
    </Route>
);
export default Routes;


回答4:

The router actually should never change, so you should be able to just return false for shouldComponentUpdate() in this case.

import React from 'react'
import ReactDOM  from 'react-dom'
import { Router, Route, Link } from 'react-router'
import App from './index/app'
import About from './index/about'
import Inbox from './index/inbox'
class Routers extends React.Component {

  shouldComponentUpdate(){
     return false;
  }

  render() {
     return ( 
        <Router>
            <Route path="/" component={App}>
              <Route path="about" component={About} />
              <Route path="inbox" component={Inbox} />
            </Route>
        </Router>
      );
    }
}


回答5:

My Solution is change "Reflux.Component" to "React.Component"

class AppRouter extends Reflux.Component {
  constructor(props){
    super(props);
    this.store = AuthStore;
  }
  requireAuth (nextState, replace, callback) {

    if (nextState.location.pathname != '/login' && nextState.location.pathname != '/logout') {
      ActionsAuth.jwt.refresh();
    }
    const token = UtilsJWT().getToken();
    if (token){
      if (nextState.location.pathname == '/login') {

        window.location.href = '/main';
      }
      callback();
    }else{
      if (nextState.location.pathname != '/login') {
      window.location.href = '/login';
      }
    }
  }
  verifyAuth (nextState, replace, callback) {
    const token = UtilsJWT().getToken();
    if (token){
      if (nextState.location.pathname == '/login') {

        window.location.href = '/main';
      }
      callback();
    }else{
      if (nextState.location.pathname != '/login') {
        window.location.href = '/login';
      }
      callback();
    }
  }

  render(){
    return (
      <Router history={browserHistory}>
          <Route path="/" component={App}>
              <IndexRoute component={Login} onEnter={ this.verifyAuth }/>
              <Route path="login" component={Login} onEnter={ this.verifyAuth }/>
              <Route path="main" component={Main} onEnter={ this.requireAuth }/>
              <Route path="logout" component={Logout} onEnter={ this.requireAuth }/>
              <Route path="local-sync" component={LocalSync} onEnter={ this.requireAuth }/>
              <Route path="*" component={Login} onEnter={ this.verifyAuth }/>
          </Route>
      </Router>
    )
  }
}



回答6:

i have the same issue,my Solution is change "import { Router, Route, Link } from 'react-router'" to "import {HashRouter, Route, Link} from 'react-router-dom'" my code:

ReactDOM.render((
    <HashRouter>
        <div>
            <ul>
                <li><Link to="/">Home</Link></li>
                <li><Link to="/login">Login</Link></li>
            </ul>
            <hr/>

            <Route path="/" exact component={createComponent(Home)}/>
            <Route path="/login" component={createComponent(Login)}/>
        </div>
    </HashRouter>
), document.getElementById('root'));



回答7:

I know this is an old question, but someone might find this useful. I tried a lot of stuff and what finally worked for me is:

import React from 'react'
import ReactDOM  from 'react-dom'
import { Router, Route, Link } from 'react-router'
import App from './index/app'
import About from './index/about'
import Inbox from './index/inbox'

class Routers extends React.Component {
   private routes = (
      <Route path="/" component={App}>
          <Route path="about" component={About} />
          <Route path="inbox" component={Inbox} />
      </Route>
   );

   render() {
      return ( 
         <Router>
            {this.routes}
         </Router>
       );
    }
}