<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>React on EricChung的程式勇者村</title><link>https://ericchung24.github.io/blog/tags/react/</link><description>Recent content in React on EricChung的程式勇者村</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><lastBuildDate>Sat, 23 May 2026 20:05:00 +0800</lastBuildDate><atom:link href="https://ericchung24.github.io/blog/tags/react/index.xml" rel="self" type="application/rss+xml"/><item><title>json-server 是什麼？前端開發很常用的假 API 工具介紹</title><link>https://ericchung24.github.io/blog/p/json-server-%E6%98%AF%E4%BB%80%E9%BA%BC%E5%89%8D%E7%AB%AF%E9%96%8B%E7%99%BC%E5%BE%88%E5%B8%B8%E7%94%A8%E7%9A%84%E5%81%87-api-%E5%B7%A5%E5%85%B7%E4%BB%8B%E7%B4%B9/</link><pubDate>Sat, 23 May 2026 20:05:00 +0800</pubDate><guid>https://ericchung24.github.io/blog/p/json-server-%E6%98%AF%E4%BB%80%E9%BA%BC%E5%89%8D%E7%AB%AF%E9%96%8B%E7%99%BC%E5%BE%88%E5%B8%B8%E7%94%A8%E7%9A%84%E5%81%87-api-%E5%B7%A5%E5%85%B7%E4%BB%8B%E7%B4%B9/</guid><description>&lt;img src="https://miro.medium.com/1*Sj1aoYWs4utJj5TfdeMlrw.png" alt="Featured image of post json-server 是什麼？前端開發很常用的假 API 工具介紹" /&gt;&lt;p&gt;前端開發最常遇到的問題之一，就是畫面想先做，但 API 還沒完成。這時候，如果還要自己手刻一個後端，只是為了讓前端有資料可以串，通常很浪費時間。&lt;code&gt;json-server&lt;/code&gt; 就是在解決這個問題。&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://www.npmjs.com/package/json-server" target="_blank" rel="noopener"
&gt;&lt;code&gt;json-server&lt;/code&gt; 的 npm 頁面&lt;/a&gt; 介紹的是一個非常實用的工具：你只要準備一份 JSON 資料，它就能快速幫你產生一組可用的 REST API。對前端工程師來說，這代表你不用等後端，也能先把列表、表單、編輯、刪除這些功能做起來。&lt;/p&gt;
&lt;h2 id="這個網站在做什麼"&gt;這個網站在做什麼？
&lt;/h2&gt;&lt;p&gt;這個網站其實是 npm 上的套件介紹頁。它的用途不是單純下載，而是讓開發者快速了解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;這個套件是做什麼的&lt;/li&gt;
&lt;li&gt;要怎麼安裝&lt;/li&gt;
&lt;li&gt;怎麼啟動&lt;/li&gt;
&lt;li&gt;支援哪些功能&lt;/li&gt;
&lt;li&gt;套件目前版本和使用狀況&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以 &lt;code&gt;json-server&lt;/code&gt; 這頁來看，頁面上可以直接看到安裝指令：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm i json-server
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;也可以看到最基本的啟動方式：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npx json-server db.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這兩個資訊就已經很夠你快速上手。&lt;/p&gt;
&lt;h2 id="json-server-的核心功能是什麼"&gt;json-server 的核心功能是什麼？
&lt;/h2&gt;&lt;p&gt;它最核心的功能，就是把一個 JSON 檔案變成一組 REST API。&lt;/p&gt;
&lt;p&gt;例如你有一個 &lt;code&gt;db.json&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;posts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;World&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;啟動 &lt;code&gt;json-server&lt;/code&gt; 後，就可以得到類似下面的 API：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GET /posts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;GET /posts/1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;POST /posts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PUT /posts/1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PATCH /posts/1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;DELETE /posts/1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這代表什麼？代表你前端原本需要後端才能做的 CRUD 流程，現在可以先自己模擬出來。&lt;/p&gt;
&lt;h2 id="為什麼前端工程師會常用它"&gt;為什麼前端工程師會常用它？
&lt;/h2&gt;&lt;p&gt;原因很實際，因為它真的省時間。&lt;/p&gt;
&lt;p&gt;第一，它可以讓前端先開發，不用卡在「API 還沒好」。
第二，它很適合做 demo、作品集、教學範例。
第三，它能讓你提早驗證資料格式和畫面流程。
第四，它的使用門檻低，不需要先寫很多後端程式。&lt;/p&gt;
&lt;p&gt;如果你是 React 開發者，這種工具特別方便，因為你可以直接拿 &lt;code&gt;fetch&lt;/code&gt; 或 &lt;code&gt;axios&lt;/code&gt; 去串它，流程和串正式 API 很接近。&lt;/p&gt;
&lt;h2 id="這個-npm-頁面還透露哪些資訊"&gt;這個 npm 頁面還透露哪些資訊？
&lt;/h2&gt;&lt;p&gt;根據我查看頁面時的內容，截至 &lt;strong&gt;2026-05-23&lt;/strong&gt;，可以看到幾個重點：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;版本是 &lt;code&gt;1.0.0-beta.15&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;每週下載量約 &lt;code&gt;332,131&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;License 是 &lt;code&gt;MIT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;GitHub repository 是 &lt;code&gt;typicode/json-server&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;有 &lt;code&gt;412&lt;/code&gt; 個 dependents&lt;/li&gt;
&lt;li&gt;累積 &lt;code&gt;165&lt;/code&gt; 個版本&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些資訊代表它不是冷門工具，而是真的有不少開發者在使用。不過也要注意，頁面顯示的版本仍然是 &lt;code&gt;beta&lt;/code&gt;，如果你要放進正式團隊開發流程，最好先確認版本相容性和使用情境。&lt;/p&gt;
&lt;h2 id="它適合用在哪些情境"&gt;它適合用在哪些情境？
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;json-server&lt;/code&gt; 很適合這幾種情況：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;前端畫面先做，但後端還沒完成&lt;/li&gt;
&lt;li&gt;想快速做一個假資料 API&lt;/li&gt;
&lt;li&gt;想練習 CRUD 串接&lt;/li&gt;
&lt;li&gt;要做作品集或 demo&lt;/li&gt;
&lt;li&gt;教學時想快速展示 API 行為&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但它比較不適合拿來當真正的正式後端。因為它的主要目的是開發輔助，不是完整商業系統的後端解法。&lt;/p&gt;
&lt;h2 id="總結"&gt;總結
&lt;/h2&gt;&lt;p&gt;如果你把 &lt;code&gt;json-server&lt;/code&gt; 想成「前端開發時的假後端工具」，這個理解基本上就是對的。它最大的價值不是功能多複雜，而是可以讓你非常快地把資料流跑起來。對前端來說，這件事很重要，因為很多畫面問題、互動問題、狀態管理問題，都要真的有 API 可以串時才會看得清楚。&lt;/p&gt;
&lt;p&gt;所以，如果你常常碰到「前端要先做，但 API 還沒來」這種情況，那 &lt;code&gt;json-server&lt;/code&gt; 是非常值得認識的一個工具。&lt;/p&gt;</description></item><item><title>新手第十五步：React 入門　前端最熱門的框架，到底在紅什麼？</title><link>https://ericchung24.github.io/blog/p/%E6%96%B0%E6%89%8B%E7%AC%AC%E5%8D%81%E4%BA%94%E6%AD%A5react-%E5%85%A5%E9%96%80-%E5%89%8D%E7%AB%AF%E6%9C%80%E7%86%B1%E9%96%80%E7%9A%84%E6%A1%86%E6%9E%B6%E5%88%B0%E5%BA%95%E5%9C%A8%E7%B4%85%E4%BB%80%E9%BA%BC/</link><pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate><guid>https://ericchung24.github.io/blog/p/%E6%96%B0%E6%89%8B%E7%AC%AC%E5%8D%81%E4%BA%94%E6%AD%A5react-%E5%85%A5%E9%96%80-%E5%89%8D%E7%AB%AF%E6%9C%80%E7%86%B1%E9%96%80%E7%9A%84%E6%A1%86%E6%9E%B6%E5%88%B0%E5%BA%95%E5%9C%A8%E7%B4%85%E4%BB%80%E9%BA%BC/</guid><description>&lt;img src="https://legacy.reactjs.org/logo-og.png" alt="Featured image of post 新手第十五步：React 入門　前端最熱門的框架，到底在紅什麼？" /&gt;&lt;p&gt;你學完 HTML、CSS、JavaScript 之後，應該已經可以做出會動的網頁了。&lt;/p&gt;
&lt;p&gt;但只要功能一變多，很快就會開始出現這些問題：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一個資料改了，很多地方都要手動更新&lt;/li&gt;
&lt;li&gt;按鈕事件越綁越多，程式碼開始打結&lt;/li&gt;
&lt;li&gt;頁面狀態一多，很難知道現在到底是哪裡出了問題&lt;/li&gt;
&lt;li&gt;同樣的 UI 要重複寫很多次&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這就是前端框架存在的原因。&lt;br&gt;
而在所有前端框架裡，&lt;strong&gt;React&lt;/strong&gt; 幾乎是目前最熱門、也最常出現在職缺上的名字。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-react-是什麼"&gt;1. React 是什麼？
&lt;/h2&gt;&lt;p&gt;React 是由 &lt;strong&gt;Meta（Facebook）&lt;/strong&gt; 開發的前端函式庫，用來建立使用者介面（UI）。&lt;/p&gt;
&lt;p&gt;你可以把它理解成一套更有組織的方式，讓你去寫：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;畫面怎麼長&lt;/li&gt;
&lt;li&gt;資料怎麼變&lt;/li&gt;
&lt;li&gt;當資料改變時，畫面怎麼自動更新&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;React 最有名的地方，不是它「能做動畫」或「能發 API」，而是它把前端畫面拆得更清楚、更容易維護。&lt;/p&gt;
&lt;p&gt;簡單說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;React 幫你把「資料」和「畫面」的關係整理好。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="2-為什麼前端要用-react"&gt;2. 為什麼前端要用 React？
&lt;/h2&gt;&lt;p&gt;先想像一個購物車頁面。&lt;/p&gt;
&lt;p&gt;當你把商品數量從 1 改成 2 的時候，頁面上很多地方都要一起改：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;商品小計要更新&lt;/li&gt;
&lt;li&gt;總金額要更新&lt;/li&gt;
&lt;li&gt;導覽列上的購物車數量要更新&lt;/li&gt;
&lt;li&gt;如果超過免運門檻，提示訊息也要更新&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你用原生 JavaScript 手動處理，通常會變成：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先抓商品數量的 DOM&lt;/li&gt;
&lt;li&gt;再抓總金額的 DOM&lt;/li&gt;
&lt;li&gt;再抓購物車 icon 的 DOM&lt;/li&gt;
&lt;li&gt;每改一次資料，就手動一個一個改畫面&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這樣在小專案還可以，但功能一多就會變得很痛苦。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;React 的想法不一樣：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;你不用一直想「我要改哪個 DOM」，你只要想：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;現在資料是什麼&lt;/li&gt;
&lt;li&gt;這份資料應該長出什麼畫面&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;當資料改變時，React 會幫你把該更新的地方更新掉。&lt;/p&gt;
&lt;p&gt;這種寫法叫做 &lt;strong&gt;宣告式（Declarative）&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="3-react-在解決什麼問題"&gt;3. React 在解決什麼問題？
&lt;/h2&gt;&lt;p&gt;React 主要在解決 3 件事：&lt;/p&gt;
&lt;h3 id="1-畫面重複利用"&gt;1. 畫面重複利用
&lt;/h3&gt;&lt;p&gt;一個按鈕、一張商品卡片、一個導覽列，常常會在網站很多地方重複出現。&lt;br&gt;
React 可以把它們拆成&lt;strong&gt;元件（Component）&lt;/strong&gt;，寫一次、重複使用很多次。&lt;/p&gt;
&lt;h3 id="2-資料和畫面同步"&gt;2. 資料和畫面同步
&lt;/h3&gt;&lt;p&gt;當資料變了，畫面要跟著變。&lt;br&gt;
React 幫你把這件事變得很自然，不需要你一直自己手動操作 DOM。&lt;/p&gt;
&lt;h3 id="3-大型專案的可維護性"&gt;3. 大型專案的可維護性
&lt;/h3&gt;&lt;p&gt;當頁面越來越多、互動越來越複雜時，React 的元件化寫法會比一大包原生 JS 更容易整理。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="4-react-的-3-個核心觀念"&gt;4. React 的 3 個核心觀念
&lt;/h2&gt;&lt;p&gt;如果你剛接觸 React，先搞懂這三個觀念就夠了。&lt;/p&gt;
&lt;h3 id="元件component"&gt;元件（Component）
&lt;/h3&gt;&lt;p&gt;React 把 UI 當成一塊一塊的小積木。&lt;/p&gt;
&lt;p&gt;例如一個網站可以拆成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Header&lt;/li&gt;
&lt;li&gt;Sidebar&lt;/li&gt;
&lt;li&gt;ProductCard&lt;/li&gt;
&lt;li&gt;Button&lt;/li&gt;
&lt;li&gt;Footer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;每一塊都可以是一個 React 元件。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Welcome&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;歡迎來到我的網站&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這就是最基本的 React 元件。它本質上就是一個函式，回傳一段 UI。&lt;/p&gt;
&lt;h3 id="props"&gt;Props
&lt;/h3&gt;&lt;p&gt;元件之間要傳資料時，會用到 &lt;strong&gt;props&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Welcome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;你好&lt;/span&gt;&lt;span class="err"&gt;，&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;Welcome&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Eric&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這樣畫面就會顯示：&lt;code&gt;你好，Eric&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;你可以把 props 想成「父元件傳給子元件的參數」。&lt;/p&gt;
&lt;h3 id="state"&gt;State
&lt;/h3&gt;&lt;p&gt;如果 props 是外面傳進來的資料，那 &lt;strong&gt;state&lt;/strong&gt; 就是元件自己管理的資料。&lt;/p&gt;
&lt;p&gt;最常見的例子就是計數器：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;react&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;目前次數&lt;/span&gt;&lt;span class="err"&gt;：&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;當 &lt;code&gt;count&lt;/code&gt; 改變時，React 會自動重新 render，畫面上的數字也會跟著更新。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="5-一個最小-react-範例"&gt;5. 一個最小 React 範例
&lt;/h2&gt;&lt;p&gt;來看一個最簡單、最能感受到 React 特色的例子。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;react&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMessage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;你好，React！&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;changeMessage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;setMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;訊息被改掉了！&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;{&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;changeMessage&lt;/span&gt;&lt;span class="p"&gt;}&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;點我換訊息&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這段做了什麼？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用 &lt;code&gt;useState&lt;/code&gt; 建立一個狀態 &lt;code&gt;message&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;畫面先顯示 &lt;code&gt;你好，React！&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;點按鈕後呼叫 &lt;code&gt;setMessage&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;React 發現 state 變了，就重新更新畫面&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這裡最重要的地方是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;你完全沒有手動去抓 DOM，也沒有自己寫 &lt;code&gt;document.getElementById()&lt;/code&gt;。&lt;/strong&gt;&lt;br&gt;
你只是在改資料，React 幫你把畫面同步更新。&lt;/p&gt;
&lt;p&gt;這就是 React 最核心的爽感。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="6-jsx-是什麼為什麼看起來像-html"&gt;6. JSX 是什麼？為什麼看起來像 HTML？
&lt;/h2&gt;&lt;p&gt;React 程式碼裡最讓新手困惑的地方，通常就是這個：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這看起來像 HTML，但它其實不是純 HTML，而是 &lt;strong&gt;JSX&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;JSX 是一種讓你可以在 JavaScript 裡面寫類似 HTML 語法的寫法。&lt;br&gt;
它的目的是讓 UI 結構更直覺、更容易閱讀。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Eric&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;你好&lt;/span&gt;&lt;span class="err"&gt;，&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這裡的 &lt;code&gt;{name}&lt;/code&gt; 代表「把 JavaScript 變數插進畫面裡」。&lt;/p&gt;
&lt;p&gt;你可以把 JSX 想成：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;用比較好讀的方式去描述 UI 長什麼樣子。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="7-react-vs-原生-javascript差在哪"&gt;7. React vs 原生 JavaScript：差在哪？
&lt;/h2&gt;&lt;p&gt;這個問題很多新手都會問，而且問得很好。&lt;/p&gt;
&lt;h3 id="原生-javascript-的做法"&gt;原生 JavaScript 的做法
&lt;/h3&gt;&lt;p&gt;你通常會：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;先抓 DOM&lt;/li&gt;
&lt;li&gt;幫按鈕綁事件&lt;/li&gt;
&lt;li&gt;在事件裡手動更新文字&lt;/li&gt;
&lt;li&gt;有更多區塊時，再一個一個更新&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這樣的好處是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;沒有額外框架&lt;/li&gt;
&lt;li&gt;很直接&lt;/li&gt;
&lt;li&gt;很適合做小功能&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但缺點是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;畫面邏輯和 DOM 操作很容易混在一起&lt;/li&gt;
&lt;li&gt;當功能變多，維護成本會快速上升&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="react-的做法"&gt;React 的做法
&lt;/h3&gt;&lt;p&gt;React 比較像是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;先定義資料&lt;/li&gt;
&lt;li&gt;再定義資料對應的畫面&lt;/li&gt;
&lt;li&gt;當資料改變時，React 幫你更新 UI&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它的優點是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;更適合大型專案&lt;/li&gt;
&lt;li&gt;元件可以重複使用&lt;/li&gt;
&lt;li&gt;狀態管理比較清楚&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以結論不是「React 取代原生 JS」，而是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;原生 JS 是基礎，React 是讓大型 UI 開發更有效率的工具。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="8-react-vs-vue新手該怎麼看"&gt;8. React vs Vue：新手該怎麼看？
&lt;/h2&gt;&lt;p&gt;你前面已經看過 Vue 文章了，那 React 和 Vue 差在哪？&lt;/p&gt;
&lt;p&gt;先講結論：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Vue&lt;/strong&gt; 對新手通常比較友善&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;React&lt;/strong&gt; 在職場上更常見，生態系也非常大&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="vue-的感覺"&gt;Vue 的感覺
&lt;/h3&gt;&lt;p&gt;Vue 的模板語法比較接近 HTML，很多新手第一次看會覺得比較自然。&lt;/p&gt;
&lt;p&gt;例如 Vue 會寫：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;count++&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;點我&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;對剛接觸前端框架的人來說，這種寫法通常比較好懂。&lt;/p&gt;
&lt;h3 id="react-的感覺"&gt;React 的感覺
&lt;/h3&gt;&lt;p&gt;React 會把 UI 和邏輯更緊密地寫在一起，用 JSX 來組合。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;點我&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;一開始你可能會覺得 React 比較「像在寫 JavaScript」，門檻稍微高一點。&lt;br&gt;
但也因為這樣，它在組合彈性和工程化上非常強。&lt;/p&gt;
&lt;h3 id="那到底學哪個"&gt;那到底學哪個？
&lt;/h3&gt;&lt;p&gt;如果你是完全新手：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vue 通常比較快上手&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你考慮求職市場：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;React 通常更值得優先投入&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不過你不用把它想成二選一。&lt;br&gt;
&lt;strong&gt;框架只是工具，重點還是你對 HTML、CSS、JavaScript 基礎有沒有真的懂。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="9-給新手的學習順序建議"&gt;9. 給新手的學習順序建議
&lt;/h2&gt;&lt;p&gt;如果你準備開始學 React，我建議順序是這樣：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先把 JavaScript 基礎打穩&lt;/li&gt;
&lt;li&gt;學 React 元件、props、state&lt;/li&gt;
&lt;li&gt;再學事件處理和列表渲染&lt;/li&gt;
&lt;li&gt;接著學 &lt;code&gt;useEffect&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;最後再碰 API 串接、路由、狀態管理&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;很多人卡住不是因為 React 太難，而是因為 JavaScript 基礎不夠穩，就直接跳進框架。&lt;/p&gt;
&lt;p&gt;React 確實有學習曲線，但只要你知道它在解決什麼問題，很多概念會突然變清楚。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="結語react-紅不是沒有原因"&gt;結語：React 紅不是沒有原因
&lt;/h2&gt;&lt;p&gt;React 之所以紅，不是因為它比較潮，而是因為它真的很適合拿來開發大型、互動複雜的前端介面。&lt;/p&gt;
&lt;p&gt;它的核心思想其實不花俏：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把 UI 拆成元件&lt;/li&gt;
&lt;li&gt;把資料和畫面關係整理清楚&lt;/li&gt;
&lt;li&gt;讓資料改變時，畫面自動同步&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只要你把這三件事理解了，React 就不會再只是「那個很紅的框架」，而是你手上很有用的工具。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;接下來你可以做什麼？&lt;/strong&gt;&lt;br&gt;
下一篇我們可以直接接著寫 &lt;strong&gt;React &lt;code&gt;useState&lt;/code&gt; 入門&lt;/strong&gt;，因為 state 是 React 最核心、也最早一定會碰到的觀念。等你把 &lt;code&gt;useState&lt;/code&gt; 和 &lt;code&gt;useEffect&lt;/code&gt; 都打通之後，React 就會開始真正連起來。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;準備好正式進入 React 的世界了嗎？下一篇見！&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>新手第十四步：React useEffect 入門　搞懂副作用，不再亂用！</title><link>https://ericchung24.github.io/blog/p/%E6%96%B0%E6%89%8B%E7%AC%AC%E5%8D%81%E5%9B%9B%E6%AD%A5react-useeffect-%E5%85%A5%E9%96%80-%E6%90%9E%E6%87%82%E5%89%AF%E4%BD%9C%E7%94%A8%E4%B8%8D%E5%86%8D%E4%BA%82%E7%94%A8/</link><pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate><guid>https://ericchung24.github.io/blog/p/%E6%96%B0%E6%89%8B%E7%AC%AC%E5%8D%81%E5%9B%9B%E6%AD%A5react-useeffect-%E5%85%A5%E9%96%80-%E6%90%9E%E6%87%82%E5%89%AF%E4%BD%9C%E7%94%A8%E4%B8%8D%E5%86%8D%E4%BA%82%E7%94%A8/</guid><description>&lt;img src="https://legacy.reactjs.org/logo-og.png" alt="Featured image of post 新手第十四步：React useEffect 入門　搞懂副作用，不再亂用！" /&gt;&lt;p&gt;很多 React 新手一看到 &lt;code&gt;useEffect&lt;/code&gt;，第一反應都是：「這個看起來很強，我是不是什麼事情都可以丟進去？」&lt;/p&gt;
&lt;p&gt;結果寫著寫著，就開始出現這些狀況：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;頁面一直重複 re-render&lt;/li&gt;
&lt;li&gt;API 被呼叫兩三次&lt;/li&gt;
&lt;li&gt;明明只是想把名字組起來，卻還多寫一個 state&lt;/li&gt;
&lt;li&gt;元件卸載後還在跑計時器，畫面越來越怪&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;useEffect&lt;/code&gt; 不是萬用工具，它是拿來處理「副作用」的。&lt;/strong&gt;&lt;br&gt;
只要你先搞懂這句話，後面大部分問題都會少很多。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-useeffect-是什麼"&gt;1. &lt;code&gt;useEffect&lt;/code&gt; 是什麼？
&lt;/h2&gt;&lt;p&gt;React 元件最主要的工作，是根據 &lt;code&gt;state&lt;/code&gt; 和 &lt;code&gt;props&lt;/code&gt; 去&lt;strong&gt;畫畫面&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;但有些事情不是單純畫畫面就能完成，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;向後端抓資料&lt;/li&gt;
&lt;li&gt;監聽視窗大小變化&lt;/li&gt;
&lt;li&gt;設定 &lt;code&gt;setInterval&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;手動改 &lt;code&gt;document.title&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;訂閱或解除訂閱外部事件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些事情都會影響元件外部，或需要和外部世界互動，這種行為就叫做 &lt;strong&gt;副作用（Side Effect）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;而 &lt;code&gt;useEffect&lt;/code&gt;，就是 React 提供給你的「副作用處理區」。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;react&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;元件渲染完成後執行&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;上面這段的意思是：&lt;strong&gt;React 先把畫面渲染出來，然後再執行 &lt;code&gt;useEffect&lt;/code&gt; 裡面的程式。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="2-什麼時候該用-useeffect"&gt;2. 什麼時候該用 &lt;code&gt;useEffect&lt;/code&gt;？
&lt;/h2&gt;&lt;p&gt;你可以先記一個最實用的判斷方式：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;如果這件事跟「畫面外部」有關，就可能要用 &lt;code&gt;useEffect&lt;/code&gt;。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;例如下面這些情況，就是典型的 &lt;code&gt;useEffect&lt;/code&gt; 使用時機。&lt;/p&gt;
&lt;h3 id="抓-api-資料"&gt;抓 API 資料
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/api/products&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="監聽事件"&gt;監聽事件
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleResize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerWidth&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;resize&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleResize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="改變瀏覽器標題"&gt;改變瀏覽器標題
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;購物車頁面&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這幾個例子有一個共同點：&lt;strong&gt;它們都不是單靠 JSX render 就能完成的事。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="3-什麼時候不該用-useeffect"&gt;3. 什麼時候不該用 &lt;code&gt;useEffect&lt;/code&gt;？
&lt;/h2&gt;&lt;p&gt;這才是新手最容易踩雷的地方。&lt;/p&gt;
&lt;p&gt;如果某個值可以直接從現有資料算出來，那就&lt;strong&gt;不要&lt;/strong&gt;再用 &lt;code&gt;useEffect&lt;/code&gt; 多繞一圈。&lt;/p&gt;
&lt;h3 id="錯誤示範把可推導的值塞進-useeffect"&gt;錯誤示範：把可推導的值塞進 &lt;code&gt;useEffect&lt;/code&gt;
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;react&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;UserCard&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fullName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFullName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;setFullName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;{&lt;/span&gt;&lt;span class="nx"&gt;fullName&lt;/span&gt;&lt;span class="p"&gt;}&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這段可以跑，但寫法不好，因為 &lt;code&gt;fullName&lt;/code&gt; 明明可以直接算出來，沒必要多一份 state。&lt;/p&gt;
&lt;h3 id="正確寫法直接算"&gt;正確寫法：直接算
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;UserCard&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fullName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;firstName&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;{&lt;/span&gt;&lt;span class="nx"&gt;fullName&lt;/span&gt;&lt;span class="p"&gt;}&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這樣更簡單，也更不容易出 bug。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;記住一句話：能在 render 階段直接算出來的東西，就不要丟進 &lt;code&gt;useEffect&lt;/code&gt;。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="4-依賴陣列到底在控制什麼"&gt;4. 依賴陣列到底在控制什麼？
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;useEffect&lt;/code&gt; 的第二個參數，通常是大家最容易看不懂的地方：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 做某些事情
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這個陣列叫做&lt;strong&gt;依賴陣列（dependency array）&lt;/strong&gt;，它在控制的是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;「哪些值改變時，這個 effect 要重新執行？」&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="1-不寫依賴陣列"&gt;1. 不寫依賴陣列
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;每次 render 都會執行&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;只要元件重新 render，這段就會再跑一次。&lt;/p&gt;
&lt;h3 id="2-傳空陣列-"&gt;2. 傳空陣列 &lt;code&gt;[]&lt;/code&gt;
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;只在初次掛載時執行&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;通常用在：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;初次載入資料&lt;/li&gt;
&lt;li&gt;初次註冊事件&lt;/li&gt;
&lt;li&gt;初始化某些外部設定&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3-傳入特定依賴-count"&gt;3. 傳入特定依賴 &lt;code&gt;[count]&lt;/code&gt;
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;count 改變了&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這表示只有 &lt;code&gt;count&lt;/code&gt; 改變時，這個 effect 才會重新執行。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="5-cleanup-是什麼為什麼很重要"&gt;5. cleanup 是什麼？為什麼很重要？
&lt;/h2&gt;&lt;p&gt;有些副作用不是做完就算了，它還需要在適當時機&lt;strong&gt;清掉&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;最常見的例子就是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;事件監聽&lt;/li&gt;
&lt;li&gt;計時器&lt;/li&gt;
&lt;li&gt;WebSocket 連線&lt;/li&gt;
&lt;li&gt;訂閱外部資料&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這時候就要用 &lt;code&gt;return&lt;/code&gt; 回傳一個清理函式，也就是 &lt;strong&gt;cleanup&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleResize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerWidth&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;resize&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleResize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;resize&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleResize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這段的意思是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;元件掛載時，註冊 &lt;code&gt;resize&lt;/code&gt; 事件&lt;/li&gt;
&lt;li&gt;元件卸載時，把事件監聽移除&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你不做 cleanup，常見結果就是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;事件越綁越多&lt;/li&gt;
&lt;li&gt;記憶體浪費&lt;/li&gt;
&lt;li&gt;元件已經不在了，副作用卻還繼續跑&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="6-給新手的實戰範例切換網頁標題"&gt;6. 給新手的實戰範例：切換網頁標題
&lt;/h2&gt;&lt;p&gt;先來看一個很簡單、但很適合理解 &lt;code&gt;useEffect&lt;/code&gt; 的例子。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;react&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`你點了 &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt; 次`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;目前次數&lt;/span&gt;&lt;span class="err"&gt;：&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;點我加一&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這段程式做了兩件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;畫面上顯示 &lt;code&gt;count&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;當 &lt;code&gt;count&lt;/code&gt; 改變時，順便更新瀏覽器分頁標題&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;為什麼這裡適合用 &lt;code&gt;useEffect&lt;/code&gt;？&lt;/p&gt;
&lt;p&gt;因為 &lt;code&gt;document.title&lt;/code&gt; 是&lt;strong&gt;React 畫面外部的東西&lt;/strong&gt;。&lt;br&gt;
React 可以控制 &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt; 裡顯示什麼，但瀏覽器標題不是 JSX 自己就會處理的，所以這種時候就該交給 &lt;code&gt;useEffect&lt;/code&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="7-新手最常犯的-3-個錯誤"&gt;7. 新手最常犯的 3 個錯誤
&lt;/h2&gt;&lt;h3 id="錯誤-1把所有邏輯都塞進-useeffect"&gt;錯誤 1：把所有邏輯都塞進 &lt;code&gt;useEffect&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;很多人一遇到資料變化，就直覺寫 &lt;code&gt;useEffect&lt;/code&gt;。但其實很多值都可以直接 render 時計算，不需要繞遠路。&lt;/p&gt;
&lt;h3 id="錯誤-2依賴沒寫完整"&gt;錯誤 2：依賴沒寫完整
&lt;/h3&gt;&lt;p&gt;如果 effect 裡用到了某個值，但依賴陣列沒放進去，就可能造成資料不同步，或拿到舊值。&lt;/p&gt;
&lt;h3 id="錯誤-3忘了-cleanup"&gt;錯誤 3：忘了 cleanup
&lt;/h3&gt;&lt;p&gt;特別是事件監聽和計時器，忘記清掉的後果通常不是立刻爆炸，而是過一段時間才出現怪問題，最難查。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="8-你可以先這樣記"&gt;8. 你可以先這樣記
&lt;/h2&gt;&lt;p&gt;如果你現在腦袋有點亂，先不用急著背細節，記住下面這個版本就夠用了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;useEffect&lt;/code&gt; 是拿來處理副作用的&lt;/li&gt;
&lt;li&gt;能直接 render 算出來的值，不要用 &lt;code&gt;useEffect&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[]&lt;/code&gt; 代表只在初次執行&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[value]&lt;/code&gt; 代表 &lt;code&gt;value&lt;/code&gt; 改變時重新執行&lt;/li&gt;
&lt;li&gt;有監聽、計時器、訂閱時，記得 cleanup&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="結語先學會少用才會真的用"&gt;結語：先學會少用，才會真的用
&lt;/h2&gt;&lt;p&gt;很多新手學 &lt;code&gt;useEffect&lt;/code&gt; 的第一個問題，是「它能做什麼？」&lt;br&gt;
但更重要的問題其實是：&lt;strong&gt;「什麼時候不該用它？」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;因為 &lt;code&gt;useEffect&lt;/code&gt; 本身不難，難的是你要分得出來：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;這是單純 render 邏輯&lt;/li&gt;
&lt;li&gt;還是這真的是副作用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只要這條線分清楚，你的 React 程式碼就會乾淨很多，也比較不容易掉進無限 re-render 的坑裡。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;接下來你可以做什麼？&lt;/strong&gt;&lt;br&gt;
下一篇如果你願意，我們可以接著寫 &lt;strong&gt;React &lt;code&gt;useState&lt;/code&gt; 與 &lt;code&gt;useEffect&lt;/code&gt; 的搭配實戰&lt;/strong&gt;，用真正的 API 抓資料、載入中狀態、錯誤處理，一次把 React 最常見的流程串起來。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;學會 &lt;code&gt;useEffect&lt;/code&gt; 之後，你就開始真的在寫 React 了。&lt;/strong&gt;&lt;/p&gt;</description></item></channel></rss>