aemoe / fairy

一个能够支持前后端分离并支持中间层同构的完整框架
http://aemoe.listenlite.com/2017/05/18/How%20to%20build/
132 stars 24 forks source link

【react热加载问题】引入react-hot-loader3之后报错 Warning: ExceptionsManager.js:76 <Provider> does not support changing `store` on the fly. It is most likely that you see this error because you updated to Redux 2.x and React Redux 2.x which no longer hot reload reducers automatically. See https://github.com/reactjs/react-redux/releases/tag/v2.0.0 for the migration instructions. Warning: [react-router] You cannot change <Router routes>; it will be ignored #3

Closed aemoe closed 6 years ago

aemoe commented 7 years ago

问题

引入react-hot-loader3之后报错 Warning: ExceptionsManager.js:76 does not support changing store on the fly. It is most likely that you see this error because you updated to Redux 2.x and React Redux 2.x which no longer hot reload reducers automatically. See https://github.com/reactjs/react-redux/releases/tag/v2.0.0 for the migration instructions. 和 Warning: [react-router] You cannot change ; it will be ignored

原因

第一个问题未知,请参考client/redux的文件夹里面的设置可以解决 第二个问题是react-router组件v2和v3版本的问题,官方说并不影响热替换

解决方案

react-router3 在使用react-hot-loader3时会出现报错的问题, 不需要管它, 这并不影响使用 如果想解决可以给router加随机数

或者更换react-router4 即可
yangfan0095 commented 7 years ago

@aemoe 加上随机数 变成了渲染整个route ,我看了https://github.com/ReactTraining/react-router/issues/2704 上面推荐把 routes 写在render 函数外面 ,但是在我的项目里面还是不能用 ,不知道为啥 ,我的版本是"react-hot-loader": "^3.0.0-beta.7", "webpack": "^2.2.1", "react-router": "^3.0.1",

yangfan0095 commented 7 years ago

![Uploading image.png…]()

aemoe commented 7 years ago

@yangfan0095 嗯 我当时也看了外国他们讨论的issue, react-hot-loader的作者说是不需要管这个提示, 并不影响热加载 我当时用V3的时候确实可以hot reload

link

aemoe commented 7 years ago

@yangfan0095 看看这个方案0 .0

根据 https://github.com/gaearon/react-hot-boilerplate/pull/61 其中 @dferber90 巨巨提出的解决方案整理

  1. 避免 react-hot-loader 失效 所有的组件必须用 const 来定义的,避免组件引用被修改,否则会使 react-hot-loader 失效。

  2. 避免 react-router 输出报错信息 这个版本 react-router 和 react-hot-loader 3 不太兼容,在每次热更新时 react-router 会报错: Warning: [react-router] You cannot change ; it will be ignored 虽然不影响热更新,但有个报错还是很影响开发的。

可以通过引入一个空对象,用 Object.assign 合并 routes 到空对象上,避免「change 」:

创建 ./config/referentially-equal-root-route.js

// referentially-equal-root-route.js
export default {}  
// Routes.js
// ...
import routeSource from './Routes'  
import referenctiallyEqualRootRoute from './referentially-equal-root-route'  
const routes = Object.assign(referenctiallyEqualRootRoute, routeSource)

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

这样修改以后, react-router 的报错便不再出现了。

  1. 为异步(Code Splitting)路由组件提供热更新 异步路由组件在修改代码后,看控制台显示热更新完成,但组件却没有变化,除非重新加载一遍这个异步组件(后退前进 或 从别的路由路径切换到这个更新的路由路径),才会更新。

(这个解决方法略微蛋疼)

在 ./config/Routes.js 中我们只要引用任何异步模块:

// ...
getComponent (nextState, cb) {  
  require.ensure([], require => {
    const Employee = require('../views/users/Employee')
    cb(null, Employee.default)
  })
}
// ...

都需要在 ./config/App.jsx (即 Root 组件) 中 require 一遍:

// ...
if (process.env.NODE_ENV !== 'production') {  
  // ... 有多少异步模块就 require 多少
  require('../views/users/Employee')
}

export default class App extends Component {  
  render () {
    return <Router history={browserHistory} routes={routes} />
  }
}

这样才能在开发环境中,对异步模块进行热更新。 (记得在 npm run build 脚本命令中加上 NODE_ENV=production)

yangfan0095 commented 7 years ago

@aemoe 谢谢 ,我的问题已解决 。我的项目里面引入了 ant-design ,在babel presets的时候 没有设置module = false , 导致webpack2 在加载模块的时候还是用的commonJs 那种方式。 所以每次 full load都是正常的 但是无法热替换, 最后看了这个issue https://github.com/gaearon/react-hot-loader/tree/master/docs#migration-to-30 在热替换的时候 用了commonjs 的方法解决了问题

// 模块热替换的 API if (module.hot) { module.hot.accept('./router', () => { // render(); const NextApp = require('./router').default; ReactDOM.render(

, document.getElementById('oss-content') ); }); } 我的babel 配置 { "presets": [ ["es2015"], "react" ], "plugins": [ "react-hot-loader/babel", ["import", [{ "libraryName": "antd", "style": true }]] ] }