終究都要學 React 何不現在學呢? - React CRA - StrictMode 與 WebVitals - (20)

前言

延續上一篇的 CRA 專案,這一天會將剩下兩成沒看過的程式碼稍微認識一下,所以這一篇也會相對簡單輕鬆。

Web Vitals

一開始我們先來看一下 index.js 最後的這一段程式碼

1
2
3
4
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

透過註解我們可以知道 reportWebVitals 就是跟網站性能有關係,所以接著我們可以打開 reportWebVitals 看一下內容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// reportWebVitals.js

const reportWebVitals = onPerfEntry => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};

export default reportWebVitals;

如果有在研究 SEO 的人,可能會注意到幾個很熟悉的單字 CLS、FID、FCP、LCP 與 TTFB,之前我的部落格也有被檢測過 LCP、FID、CLS 中的 CLS 不合格過,而這個東西就是 Google 網站核心指標。

基本上 reportWebVitals 就是跟網站核心指標有關,因此你如果要使用的話,只需要回到 index.jsreportWebVitals 改成 reportWebVitals(console.log);,這樣子就可以在瀏覽器的控制台看到相關數據與結果。

console.log

因此 reportWebVitals 就是跟網站核心指標有關,而這個東西就是 Google 網站核心指標。

StrictMode

接著我們回到前面一點的程式碼部分,底下範例程式碼我稍微精簡了一下,只著重於即將要說明的東西上

1
2
3
4
5
6
7
8
9
10
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

前面許多章節中,我們並沒有特別說明與使用到 StrictMode(React.StrictMode),那 StrictMode 到底是什麼呢?簡單來講類似於 JavaScript 的嚴格模式 'use strict';

但 React 中的 StrictMode 有什麼特色呢?基本上只要被 <React.StrictMode> 包覆的元件都會具備以下效果

  • 發現擁有不安全生命週期的 component
  • 警告使用了 legacy string ref API
  • 警告使用到了被棄用的 findDOMNode
  • 偵測意想不到的副作用
  • 偵測 legacy context API
  • 確保可重用的 state

以上都是 React 官方所提供的說明。

簡單來講就是讓你程式碼可以更具有安全性。

但是這邊有一個地方要注意,如果你是這樣子寫的話

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

import Header from './Header';
import Footer from './Footer';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Header />
<React.StrictMode>
<App />
</React.StrictMode>
<Footer />
);

<Header /><Footer /> 元件就不會吃到 StrictMode 模式,而是只有 <App /> 底下的元件、子元件才會被設置為 StrictMode 唷。

那麼回頭簡單講一下使用 StrictMode 之後會發生什麼事情呢?所以這邊我們就要來寫一個簡單的範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function App() {
return (
<div>
<h1>React StrictMode</h1>
<p>這是一個 StrictMode 的測試範例</p>
</div>
);
}

const root = ReactDOM.createRoot(document.querySelector('#root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

在這個範例中,我們只有一個元件,並沒有使用到任何的生命週期,因此你並不會看到什麼奇怪的錯誤訊息,但這時候你嘗試使用 useEffect 來做一些事情,那麼結果就會有一點不一樣了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function App() {
React.useEffect(() => {
console.log('useEffect');
}, []);

return (
<div>
<h1>React StrictMode</h1>
<p>這是一個 StrictMode 的測試範例</p>
</div>
);
}

const root = ReactDOM.createRoot(document.querySelector('#root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

打開 Console 後你會發現 useEffect 執行了兩次,正常來講只會執行一次,會發生這個原因是因為 StrictMode 會偵測到你的元件是否有不安全的生命週期,因此會執行兩次,這樣的做法是為了讓你可以更容易的找到問題所在。

如果對於 StrictMode 有興趣的話,可以參考 React 官方文件 或是這一篇的討論。

後記

本文將會同步更新到我的部落格