我正在使用react-hot-loader,我对其示例代码非常困惑:
import React from 'react'
import ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import App from './containers/App'
ReactDOM.render(
<AppContainer>
<App/>
</AppContainer>,
document.getElementById('root')
);
// Hot Module Replacement API
if (module.hot) {
module.hot.accept('./containers/App', () => {
const NextApp = require('./containers/App').default;
ReactDOM.render(
<AppContainer>
<NextApp/>
</AppContainer>,
document.getElementById('root')
);
});
}
我不明白的是:
a)为什么我需要使用App和NextApp? App
与NextApp
不一样,因为它们是从同一个文件导入的吗?
b)我认为最佳做法是将requires
保留在代码的开头。但我已经import App from '../containers/App
'了。所以:
import App from './containers/App'
const NextApp = require('./containers/App').default;
App
和NextApp
不应该相同吗?
c)要完成,以下代码行是否等效?使用纯require
和require .default
?
const NextApp = require('./containers/App');
const NextApp = require('./containers/App').default;
很抱歉,如果这些是非常基本的问题,但我需要提示如何更好地理解此代码。
答案 0 :(得分:13)
为了更好地理解这一点,您需要了解webpack offers hot module loading对其他非反应案例的看法。
实际上这个想法非常简单...... Webpack检测到代码发生的变化并重新编译相应的模块。但是,它无法安全地替换模块引用本身。这就是您需要自己实现HMR接口的原因,因此您的示例代码中会调用module.hot
。
当一个较新版本的模块可用时,Webpack上升到模块链(即,如果X导入Y和Y已经改变,webpack开始从X&gt; W&gt; V ...开始)直到它找到一个为Y或X或W或V等实现HMR的模块然后从那里重新加载整个链。
如果它在没有任何HMR接受更改的情况下到达root,它将刷新整个页面:)。
现在App和NextApp的问题... App是你模块的静态导入版本。由于模块在默认情况下仅被解析和加载一次,因此App指向永不改变的常量引用。这就是在示例中使用另一个变量NextApp的原因,该变量接收HMR代码中的已更改模块。
最后,require和require.default ...在处理ES6导入(导出默认MyComponent)时,导出的模块的格式为{“default”:MyComponent}。 import
语句正确地为您处理此分配,但是,您必须自己进行require("./mycomponent").default
转换。 HMR接口代码无法使用import
,因为它不能内联工作。如果您想避免这种情况,请使用module.exports
代替export default
。