iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 9
1
Modern Web

從比入門再往前一點開始,一直到深入React.js系列 第 9

【Day.09】React入門 - Hello world、React virtual DOM、webpack-dev-server

(2024/04/06更新) 因應React在18後更新了許多不同的語法,更新後的教學之後將陸續放在 新的blog 中,歡迎讀者到該處閱讀,我依然會回覆這邊的提問


第一個React程式 - Hello world

請將src/index.js的程式碼改為:

import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render( <div>hello React!</div> , document.getElementById('root') );

接著執行webpack -p或是npm run build,打開build/index.html,你會看到:

我們的第一個React程式就完成了。

剛剛做了什麼事情 - 談談React Virtual DOM

在原生的Javascript中,我們會直接用document.屬性 = 新值來修改網頁程式(也就是操作DOM)。 然而這樣做,很容易會不小心修改到不需要更動的地方,造成資源的浪費。

設計React的工程師為了解決這件事,讓React程式碼在更新DOM之前,先用Javascript製造出一個模擬的DOM,用這個 Virtual DOM模擬所有「更新後應該要長的樣子」,由於網頁程式文件(DOM)的架構就像是一棵樹,所以工程師引入資料結構中樹的Traversal概念,設計出一個特殊的Diff演算法去比較「模擬好未來長怎樣的虛擬DOM」和「當前DOM」所有節點的差別。最後,React就只會去修改「有不一樣的地方」,達到避免資源浪費的效果。

參考文件

請注意由於多了一層上述過程,引入Virtual DOM會讓更新的速度比直接操作DOM API慢(只不過通常沒感覺),Virtual DOM只是讓資源浪費最小化而已。

所以回過頭來看剛剛的程式碼:

ReactDOM.render( <div>hello React!</div> , document.getElementById('root') );

要使用ReactDOM渲染畫面的函式render(中文翻譯為渲染)很簡單,第一個參數是「要渲染到畫面上的元素」,第二個參數是「第一個參數要放在哪個HTML元素內」。以這裡為例就是把<div>hello React!</div>丟到之前在build/index.html<div id="root"></div>裡面。

一般的做法是之後專案所有對於對於網頁元素的操作都丟到第一個參數,透過這一行ReactDOM.render處理。也就是所有專案的元素都會被React包進build/index.html<div id="root"></div>裡面。

不過看到這裡,你應該會有一個很大很大的疑惑:

為什麼第一個參數是HTML程式碼不是字串,卻不會有任何問題呢?

這就是React所使用的JSX語法所導致的。我們會在下一篇來聊聊JSX是什麼,以及他怎麼運作。

環境設定 - 安裝webpack-dev-server

如果每次開發都要npm run build才能檢查結果,那真的是一件很煩的事情。

webpack-dev-server就是一款能讓你一改程式碼就能預覽到結果的開發工具。

1. 請打開terminal,輸入:

npm install webpack-dev-server -g

2. 修改webpack.config.js:

  • webpack.config.js
const path = require('path');
module.exports = {
    entry: {
        index: './src/index.js'
    },
    output: {
        filename: 'bundle.js',
        path: path.resolve('./build'),
    },
    module: {
        rules: [
            { 
                test: /.js$/,
                exclude: /node_modules/,
                use: { 
                    loader: 'babel-loader',
                    options: { 
                        presets: ['@babel/preset-react', '@babel/preset-env'] 
                    } 
                } 
            },
        ]
    },
    //------ 加入以下內容 ------
    devServer: {
        contentBase: './build', // 本來打包完的檔案位置
        port: 8080 // 預覽網頁要跑在哪個port
    }
};

3.(非必須) 修改package.json

package.json

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack -p",
    //加入這行
    "dev": "webpack-dev-server" 
  }

4. 大功告成

之後每次開發前,只要先輸入

npm run dev

或是

webpack-dev-server

打開瀏覽器的localhost:8080。接著每次修改編譯前的檔案時,就能馬上預覽到結果


請注意這裏只是開發使用,因為還沒有編譯、打包,你不能直接就把沒打包的檔案丟到伺服器上。webpack-dev-server編譯出來的結果也可能會和build之後的結果不一樣。

另外如果語法有錯的話,webpack-dev-server就會無法讓你預覽,並顯示編譯結果有誤喔


上一篇
【Day.08】React入門 - 環境設定 - npm、Webpack、Babel
下一篇
【Day.10】React入門 - JSX語法
系列文
從比入門再往前一點開始,一直到深入React.js30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
denzo
iT邦新手 5 級 ‧ 2022-01-05 11:19:47

感謝您的文章,邏輯清晰且內容豐富,對剛入門的我幫助非常大!

另外小弟在運行npm run dev時有出現 webpack.config.js 中的 devServer 設定 contentBase 報錯,google後將 contentBase 改為 static 即可正常運行。

我也遇到了同樣的問題,謝謝

0
eddiechang4507
iT邦新手 4 級 ‧ 2023-10-21 16:59:44

感謝您的文章,對剛入門React的我幫助非常大!
有發現在新版本的需要再
module.exports 加入
mode: 'development',
不然會出現錯誤

我要留言

立即登入留言