React基礎——更快的開發

莫珂發表於2018-04-01

在上一篇文章《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主頁

相關文章