React基础——更快的开发

1,537 阅读3分钟

在上一篇文章《React基础——快速搭建开发环境》中我们提到了如何迈上开发React的第一步,这一篇文章中我们就来谈谈如何提高开发效率开启Hot-Module-Replacement以及使用react-hot-loader

什么是HMR

Webpack官网上写到 Hot Module Replacement (HMR) exchanges, adds, or removes modules while an application is running, without a full reload.

Hot Module Replacement简单的来说就是当你修改了应用时候,不让整个应用刷新的东西。还没有概念?请看下面两幅图(图1实时更新,没有开启HMR;图2实时更新,开启HMR),仔细找找有什么区别?

Live-Reload

HMR

估计大多数同学没看出区别。。。 请注意浏览器上方的刷新按钮,图一当我们修改代码的时候整个页面刷新了,图二页面并没有刷新只是修改了对应的内容,这样无疑可以结余开发时间

如何开启HMR

其实开启HMR非常简单,我们只需要修改自己的程序入口,在我们的例子中是src/index.js文件,修改如下:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

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

//加入下面的几行代码
if (module.hot) {
    module.hot.accept('./App', () => {
        ReactDOM.render(<App />, document.getElementById('root'));
    })
}

registerServiceWorker();

这里还需要提一下,如果使用了Redux(当然如果你是新手可以跳过关于Redux这段配置,短时间内还用不上),开启HMR需要在create store的时候进行修改:

import { createStore } from 'redux'

import rootReducer from './reducers'

const configureStore = () => {
  const store = createStore(rootReducer)

  if (process.env.NODE_ENV !== "production") {
    if (module.hot) {
      module.hot.accept('./reducers', () => {
        store.replaceReducer(rootReducer)
      })
    }
  }

  return store
}

export default configureStore

开启HMR之后,已经可以做到网页自动刷新了,但实际上还可以进一步提高开发效率,我们做个例子: 修改App.js如下:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  state = {
    count: 0
  }
  addHandler = () => {
    this.setState(prevState => {
        return { count: prevState.count+1 }
    })
  }
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          change Count={this.state.count}
          <button onClick={this.addHandler}>Add</button>
        </p>
      </div>
    );
  }
}

export default App;

之后运行代码,点击Add,此时count已经变成1了,我们再修改文字,可以看到count的数值又变成0了,如果我们可以让count的数值不受影响该多好呀?下面我们就来使用react-hot-loader来实现这一点

使用react-hot-loader

react-hot-loader是在webpack HMR基础上增加了刷新页面时候依然应用保留状态的一个插件

首先我们需要调用yarn eject来弹出配置webpack的配置信息,在新生成的config文件夹下找到webpack.config.dev.js找到下图所示代码片段,加入plugins: ["react-hot-loader/babel"] 的配置(这里实际上是给webpack增加了一个plugin插件的配置)

 // Process JS with Babel.
{
    test: /\.(js|jsx|mjs)$/,
    include: paths.appSrc,
    loader: require.resolve('babel-loader'),
    options: {
      
      // This is a feature of `babel-loader` for webpack (not Babel itself).
      // It enables caching results in ./node_modules/.cache/babel-loader/
      // directory for faster rebuilds.
      cacheDirectory: true,
      //加入下面这一句
      plugins: ["react-hot-loader/babel"]
    },
},

其次修改我们的根组件App.js如下:

import { hot } from 'react-hot-loader';

//这里是组件的定义,用省略号表示
...

export default hot(module)(App);

这里说明一下这里的hot实际上实现了上述我们谈到的HMR的功能以及保存状态的功能,因此我们的index.js文件下不用重复设置HMR的代码了

刷新页面,点击Add,此时count已经变成1了,我们再修改文字,可以看到count的数值并没有受到影响

React-Hot_Loader

这样在实际的项目中,可以保存状态又可以帮我们省去很多开发时间

更多学习链接:

hot-module-replacement

Github CRA中开启HMR的讨论

React-Hot-Loader Github主页