前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React + Redux 开启 HMR/Hot Loader

React + Redux 开启 HMR/Hot Loader

作者头像
szhshp
发布2022-09-21 10:18:04
4670
发布2022-09-21 10:18:04
举报

最近在用 React 以及 Redux 写几个项目, 使用的是官方 Create-React-App 的脚手架, 默认没有开启 HMR, 每次都要等他自动刷新浏览器效率非常低, 因此考虑使用 HMR 模式

Create-React-App 开启热替换

如果没有使用 Redux, 单纯使用官方脚手架的话其实很简单, index.js 里面加上这句就可以:

代码语言:javascript
复制
  if (module.hot) {
    module.hot.accept();
  }

Create-React-App + Redux 开启热替换

如果按照上方的方法,直接开启热替换的话, 可能出现 state 被重置的问题。 比如我 toggle 了某个控件, 修改代码热替换完毕之后, 需要重新 toggle 一次, 因为 toggle 之后的状态被重置了,这个很可能是因为所有的状态都被 reduxProvider 接管了。

不过其实也有办法。

首先要安装三个重要的库:

代码语言:javascript
复制
npm install react-app-rewired react-app-rewire-hot-loader react-hot-loader

根目录创建一个 config-overrides.js 文件, 注意是在根目录,而不是在 src 文件夹下面:

代码语言:javascript
复制
  const rewireReactHotLoader = require('react-app-rewire-hot-loader');

  module.exports = function override(config, env) {
    config = rewireReactHotLoader(config, env);
    return config;
  }

如果使用的是普通的 Create-React-App 脚手架, 那么就直接修改 index.js:

代码语言:javascript
复制
  import React from 'react';
  import ReactDOM from 'react-dom';
  import './index.css';
  import App from './App';
  import registerServiceWorker from './registerServiceWorker';

  // Add this import:
  import { AppContainer } from 'react-hot-loader';

  // Wrap the rendering in a function:
  const render = Component => {
    ReactDOM.render(
      // Wrap App inside AppContainer
      <AppContainer>
        <Component />
      </AppContainer>,
      document.getElementById('root')
    );
  };

  // Do this once
  registerServiceWorker();

  // Render once
  render(App);

  // Webpack Hot Module Replacement API
  if (module.hot) {
    module.hot.accept(() => {
      render(App);
    });
  }

另外需要修改一下 package.json:

代码语言:javascript
复制
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test":  "react-scripts test --env=jsdom"
  }

修改成:

代码语言:javascript
复制
  "scripts": {
  "start": "react-app-rewired start",
  "build": "react-app-rewired build",
  "test":  "react-app-rewired test --env=jsdom"
}

启动的时候会自动寻找根目录下面的 config-overrides.js 文件, 然后所有的设置都全部完成, npm start 体验一下 HMR 吧。

2020-1-28 更新: does not support changing store on the fly

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/reduxjs/react-redux/releases/tag/v2.0.0 for the migration instructions.

其实就是旧版本的 module.hot.accept 方法使用有一些变化.

以前的方法:

代码语言:javascript
复制
  if (module.hot) {
    module.hot.accept();
  }

现在需要显式调用:

代码语言:javascript
复制
// Webpack Hot Module Replacement API
if (module.hot) {
  module.hot.accept(() => {
    ReactDOM.render(
      <Provider store={store}>
        <App />
      </Provider>,
    );
  });
}

这里是一个例子, 和文首提供的方法一样:

代码语言:javascript
复制
const store = createStore(
  Reducer, /* reducer */
  composeEnhancer(
    applyMiddleware(thunk), /* enhancer(middleware) */
  ),
);

const render = (Component) => {
  ReactDOM.render(
    <Provider store={store}>
      <Component />
    </Provider>,
    document.getElementById('root'),
  );
};

// Do this once
registerServiceWorker();

render(App);

// Webpack Hot Module Replacement API
if (module.hot) {
  module.hot.accept(() => {
    render(App);
  });
}

参考文献

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-09-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Create-React-App 开启热替换
  • Create-React-App + Redux 开启热替换
  • 2020-1-28 更新: does not support changing store on the fly
  • 参考文献
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档