🔍 搜尋結果:html

🔍 搜尋結果:html

能提高工作效率的神奇 VSCode 外掛

原文出處:https://dev.to/lundjrl/vscode-extensions-to-magically-accelerate-your-productivity-2lad 閱讀本文的大多數人可能每天都會使用 VSCode 擴充功能。無論是檢查程式碼、顯示建議、類型推理還是讓您發笑的東西,它們都會影響您的工作流程並幫助您建立產品。 以下是我每天使用的擴充功能清單。可以肯定地說,如果沒有他們,我會完全迷失方向,而且我對門票的估計也會膨脹。 我希望這些對您的幫助就像對我的幫助一樣! --- ## Auto Rename Tag 此清單的開頭是自動重命名標籤擴充。如果您使用大量 HTML,此擴充功能非常有用。它的一般要點是它將您正在編輯的標籤的結束標籤格式化為相同的名稱,這樣您就不必這樣做。當我處理具有包含 100 多個其他標籤的標籤的「*.html」檔案的舊網站時,這為我節省了大量時間。 ID:formulahendry.auto-rename-tag VS 市場連結:https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag --- ## Code Spell Checker 如果您與國際團隊合作或您想要記錄專案中的單字或縮寫,這一點非常有用。 程式碼拼字檢查器可讓您修復拼字錯誤的單字或將它們儲存到專案的「settings.json」檔案中。這表明了對於可能不熟悉應用程式業務短語的新開發人員的巨大意圖。 ID:streetsidesoftware.code-spell-checker VS 市場連結:https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker --- ## EditorConfig EditorConfig 對我和我的團隊來說至關重要。透過建立格式化標準,它可以幫助我們在發出拉取請求時保持程式碼編輯器同步並減少差異日誌。 ID:EditorConfig.EditorConfig VS Marketplace 連結:https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig --- ## Eslint 和 Prettier 如果您進入 Webdev 世界很短一段時間,您可能已經遇到過這兩個。我不會在這裡討論太多細節,但簡而言之,Eslint 是一個 linter,Prettier 是一個格式化程式。您可以將它們一起使用以在專案中強制執行程式碼標準。 ID:dbaeumer.vscode-eslint VS 市場連結:https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint ID:esbenp.prettier-vscode VS 市場連結:https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode --- ## Git-Rename 如果您想重新命名檔案或更改檔案名稱的大小寫,Git-Rename 非常有用。 Git-Rename 允許您重命名檔案並幫助您追蹤 Git 中的這些更改,而不是刪除檔案以將其從 Git 歷史記錄中刪除以便更改其大小寫。 什麼? 假設您的專案中有一個名為“myfile”的文件,並且它已被版本控制追蹤。如果您將名稱更改為“myFile”,這只是大小寫更改,Git 預設不會關心它。您可以更改 git 設定來解決此問題,但如果您在團隊中工作,則需要說服其他開發人員也這樣做。一個更簡單的選擇是將此擴充功能包含在專案中的「extensions.json」檔案中,這樣他們每次開啟專案時都會收到提示,要求他們下載該擴充功能。 ID:ambooth.git-rename VS 市場連結:https://marketplace.visualstudio.com/items?itemName=ambooth.git-rename --- ## Import Cost 導入成本讓您知道每個導入的包有多少位元組。它對於行動應用程式非常有用,因為您的捆綁包大小對最終用戶來說意義重大。 ID:wix.vscode-導入成本 VS 市場連結:https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost --- ## IntelliCode TypeScript 和 JavaScript 的另一個很棒的擴充功能。 IntelliCode 就像那個試圖完成你的句子的煩人的朋友。它為在專案中找到的 TS 版本提供方法/物件補全,並為您推斷類型,讓您知道可以使用物件的哪些屬性。 對於 Django 粉絲來說,它也適用於 Python! ID:VisualStudioExptTeam.vscodeintellicode VS Marketplace 連結:https://marketplace.visualstudio.com/items?itemName=VisualStudioExptTeam.vscodeintellicode --- ## Pretty Typescript Errors 這並不適合所有人,但我寫了很多 TypeScript,它可以幫助我解析 TS 錯誤。基本上,這個擴充功能將顯示一條更人性化的訊息,而不是 TypeScript 給你一個長而半複雜的訊息,以幫助你縮小程式碼中錯誤的範圍。 ID:yoavbls.pretty-ts-errors VS 市場連結:https://marketplace.visualstudio.com/items?itemName=yoavbls.pretty-ts-errors --- 您使用這些擴充功能嗎?您是否有比這些更好的擴充功能的建議?請在下面的評論中告訴我!

您的下一個專案,可以試試看 HTMX 技術!

原文出處:https://dev.to/turculaurentiu91/why-you-should-choose-htmx-for-your-next-project-o7j 在本文中,我們將旨在了解為什麼您下次為 Web 應用程式選擇技術堆疊時應該考慮 HTMX 作為 React 的替代品。我們將研究傳統 HTTP JSON API + React 帶來的複雜性和挑戰,以及如何透過使用 HTMX 輕鬆避免它們。 **注意**:在本文中,我將討論 React,但它可以替換為任何其他前端框架,如 Angular、Vue、Svelte 或 Solid,但我談論 React 是因為它是大多數 Web 的預設技術開發人員預設為。 ### HTMX 到底是什麼 如果您還不知道,[HTMX](https://htmx.org/) 是一個小型瀏覽器 (JS) 庫,它使用一些屬性擴展了 HTML,允許您使用來自伺服器。它還使 HTML 能夠對所有動詞發出 HTTP 請求,而不僅僅是 GET 和 POST。 ## React 解決了什麼問題 React 是一個 JavaScript 程式庫,可協助您透過保持使用者介面與狀態同步來編寫高度互動的應用程式。您告訴它如何渲染給定的狀態,每次更新狀態時,它都會重新渲染(盡可能有效率)UI 以反映狀態變更。 每次狀態發生變化時,您都會通知庫它發生了變化,並提供新的狀態,它將處理 UI 更新。 需要本地記憶體狀態的高互動應用程式的範例可以是您可以在網路上找到的各種文字編輯器(VSCode)之一、拖放看板(如 Trello 或 JIRA)、視訊播放器或聊天室。 什麼不是此類應用程式的範例?您正在建立的待辦事項清單、您正在閱讀的新聞網站、您發布的部落格以及周圍的大多數網站。如果我們看一下 [80/20 規則](https://en.wikipedia.org/wiki/Pareto_principle) >80% 的結果來自 20% 的原因,80% 的結果來自 20% 的努力。 你可以說 80% 使用 React 的 Web 應用程式不需要本地狀態。對於那 20% 需要它的人來說,你可以說它只是應用程式的一小部分(大約 20%),其餘部分只能用 HTML 來表達。 **這些數字是編造的,我沒有任何研究來支持這一點** ## React 也解決了哪些問題,使其被現代網站廣泛採用 HTML 已經過時了。使用 HTML 製作應用程式的舊方法涉及頁面、連結和表單的集合,這些頁面、連結和表單向使用者描述給定資源的當前狀態以及他們可以執行哪些操作來更改它。 每次使用者與資源互動時,應用程式只能重新載入整個頁面以顯示資源的新狀態。 幾年後,FaceBook 推出了 React,這是一個 JS 程式庫,可讓開發人員建立單頁應用程式 (SPA)。導航時不再需要重新加載整個頁面,狀態更新的酷過渡、對用戶的有趣反饋以及其他使 Web 開發人員在其網站中採用 SPA 框架的細節。 ## 複雜性問題 ![AI 產生圖像,透過 next.js 展示現代應用程式的瘋狂複雜性](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xpk0v0nz0d45hv91i166.png) 如果你不理解上面的架構,不用擔心,沒有什麼好理解的。我要求 ChantGPT 為我生成它,由於它過於複雜且沒有任何意義,它完美地反映了現代 Web 應用程式目前的預設基礎架構。 一個很酷的程式設計原則是**KISS**,它代表“保持簡單,愚蠢”,或者有些人可能喜歡開玩笑,“保持簡單,愚蠢!” 現代開發人員預設建立 Web 應用程式的當前基礎設施和技術堆疊極其複雜,做了很多不必要的事情,只是因為它很酷! 當您自己建立第一個 POC 時,效果很好,但下一刻您加入了更多團隊成員,並且使用多次迭代和「擁抱」更改的敏捷方式,它有點崩潰,原因是我們將往下看一下。 ## 傳統 HTTP JSON API + React 的狀態管理問題 在 Web 應用程式中,您經常要做的就是從資料庫中獲取資源的狀態並將其呈現給使用者。讓我們以任務管理應用程式為例。使用者有一個任務列表,每個任務都有一個狀態: - 任務的標題 - 說明 - 任務完成時的標誌 - 截止日期(可選) 我們通常將此狀態儲存在資料庫中,並將此資訊呈現給用戶,您必須: - 從使用者有權存取的資料庫中取得所有任務。 - 可以選擇轉換資料(也許您儲存完成的日期並從中計算「is_completed」標誌)。 - 將資料序列化為 JSON。 - 透過 HTTP 請求取得資料。 - (可選但通常)根據模式驗證資料,可能使用 YUP 或 ZOD。 - 使用 Redux、Zustand、react-query 或其他狀態管理庫將 JSON 轉換為狀態並將其儲存在快取中。 - 轉換 HTML 中的狀態,通常會決定使用者可以使用資料做什麼。 簡而言之,我們正在描述如何在 JavaScript 中渲染所有資源的所有可能狀態,在瀏覽器中下載所述 JavaScript,然後 JavaScript 下載一堆 JSON 格式的資料並將其渲染(如果它知道如何)瀏覽器顯示為HTML! 向使用者顯示任務清單需要做大量工作,特別是當任務僅在使用者變更時才更改時,應用程式必須將應用程式置於載入狀態,發出另一個 HTTP 請求(以PUT 或PATCH 或DELETE)使快取值(狀態)無效並重新獲取它以顯示更改的任務。 或者更糟的是,當用戶更改某些任務時,樂觀地更新本地狀態並立即顯示更改,並在幕後執行更新請求,僅在他們成功更新後通知用戶更新失敗。 這是非常容易出錯的。對於這個待辦事項應用程式來說,它可能會很有效,因為您是唯一的開發人員,並且該應用程式足夠大,您可以在腦海中保留正在發生的所有事情的地圖。但是當你的團隊規模更大時,尤其是當你將團隊分成前端和後端時,溝通不良可能會導致很多問題。 後端可能使用“is_completed”標誌,而前端可能需要“is_active”標誌。後端可能會將經過 Markdown 處理的「描述」傳送到 HTML,而前端可能希望它不被處理。後端可能會將“描述”設為可選,以允許使用者在前端不同步時保存草稿,並且您會看到許多“未捕獲的類型錯誤:無法讀取未定義的屬性(讀取“toLowerCase” )” 另一方面,在 HTMX 上,您可以直接在範本上呈現 HTML,只要後端語言允許,就可以確保類型安全。您僅向瀏覽器發送相關訊息,向使用者提供對資源的適當控制,並指示瀏覽器或 HTMX 如何解釋使用者操作以及後端對這些操作的回應。所有應用程式狀態都是 HTML,這個概念稱為 [HATEOAS](https://htmx.org/essays/hateoas/) ## 傳統 HTTP JSON API + React 對文件的需求 為了讓兩個團隊(後端和前端)獨立工作並透過 HTTP JSON API 進行通信,您需要擁有適當的 API 文件。您還需要記錄如何計算使用者可以對給定資源執行哪些操作以顯示控制項。 大多數此類文件寫起來都很痛苦,特別是因為通常需要在實作之前編寫,而開發人員尚未完全理解問題的範圍,因此前端可以並行開發。這通常會在開發過程中進行許多更新,以適應開發過程中出現的問題,並可能導致團隊之間的版本不一致。 您還需要對 API 進行版本控制,並注意不要在非主要版本變更中引入重大變更。您無法再在不變更主要版本的情況下變更欄位名稱。您還需要保持 API 的多個版本運作或強制前端團隊進行調整。 大多數時候,文件已經過時了。有些必須緊急修復,有些新要求是在發布前一天提出的,現在您的文件已經過時,即使在很短的時間內。而且您必須記住更新它,或者更糟的是,您建立了一張票來記住它,而其他人拿起它,但沒有完整的圖片並記錄了錯誤! ## 重複的邏輯問題 對於每個資源,您必須實施授權策略。您必須確定目前使用者是否可以將任務 **46234** 標記為已完成。您必須在後端程式碼的某個位置編寫此檢查。否則,您的應用程式將開放給_不安全的直接物件參考_,或任何使用 Postman 的人都可以將您的任務標記為已完成。 您還必須在前端實現相同的邏輯,僅當用戶有權標記已完成時才顯示標記按鈕(讓我們假設您可以與其他用戶共享您的任務,但只有您可以更改它們)。 現在每次這個邏輯改變時,你都必須在兩個應用程式中實作它,並同時發布它或擁有多個版本的API。 ## 效能問題 為了使用 React 在瀏覽器中呈現網站,您需要將佔用大量內存和解析/處理影響的 React 程式碼、狀態管理庫程式碼、腳趾 UI 庫程式碼、CSS-IN- 捆綁在一起。JS 庫程式碼、應用程式程式碼以及我們透過NPM 安裝和使用的任何js 程式庫(我們並不羞於安裝新套件,請參閱[leftpad 問題](https://www.theregister.com/2016/03/23/npm_left_pad_chaos/))。這通常會導致透過網路傳送大塊的 JavaScript 資源。當然,您可以在瀏覽器中緩存,但在現代敏捷開發中,每個衝刺至少部署一次,因此這無法解決任何問題。這會消耗網路流量和電池,這對行動裝置來說是一個經常被忽視的問題。 上述JavaScript需要由瀏覽器來解釋,消耗處理能力和電池。 JavaScript,尤其是 ReactDOM,需要追蹤 DOM 的鏡像。在其之上加入普通 DOM 和本地狀態緩存,以及所有渲染函數,以及所有“useMemo”、“useCallback”和“useState”。也要加入需要在記憶體中保存所有上下文變數的所有閉包。 JavaScript 引擎並不以其記憶體效率而聞名!您會聽到人們抱怨瀏覽器消耗了多少內存,但他們低估了他們存取的網站所消耗的內存量。 所有這些加起來,最終會耗盡用戶的電池和記憶體。當然,您可以付出努力並優化所有這些,或使用其他程式庫(如 Svelte),但所有這些努力都可以用於為您的用戶提供更有意義的功能。 ## 服務端渲染的需要 近年來,我們播種了伺服器端渲染專用框架(如「Next.js」)的興起。它們的流行凸顯了對以 HTML 格式交付內容的需求,特別是出於可存取性優化、效能和搜尋引擎優化的原因。 你不想等待瀏覽器下載 JavaScript 來渲染頁面,然後等待 JavaScript 發出 HTTP 請求來獲取內容然後渲染它,你希望它立即渲染,特別是對於上面的情況折疊內容。 這又增加了一層複雜性,包括: - 基礎設施,現在您還需要另一台伺服器用於前端應用程式 - 程式碼更複雜,包括什麼程式碼在伺服器上執行以及什麼在瀏覽器上執行的思維導圖 - 部署管道現在更加複雜 - 測試基礎設施現在更加複雜 - 現在解決問題變得更加困難,您需要了解問題是在瀏覽器上、在客戶端應用程式伺服器上還是在 API 伺服器上 ## 解決這些問題 Web 開發社群各自使用自己的語言或開發技術,以不同的方式解決這些問題: - Next.js(以及 Nuxt 等) - 反應伺服器元件 - 拉維爾 - 慣性.JS - 活線 - 點網 - Blazor 頁面 - 靈藥 - 鳳凰即時查看 - 鐵鏽 - 樂浦伺服器功能 還有許多我忘記或從未聽說過的其他解決方案! 無論如何,此類解決方案的存在和流行證明了這些問題是有效的並且在 Web 開發人員的日常生活中遇到過。否則他們不會不遺餘力地解決這些問題,尤其是以開源的方式! 還有 [Turbo](https://turbo.hotwired.dev/) 以及採用它們的框架、Ruby on Rails、PHP Symphony 以及其他可能以與 HTMX 相同的方式解決相同問題的框架。選擇 HTMX 只是個人喜好,但你絕對應該了解這一點,這和 HTMX 一樣酷! 在所有這些中,HTMX 脫穎而出,不僅因為它不會將您鎖定到特定技術,您可以透過對模板進行微小更改來從 PHP 切換到 Rust,而且還因為它完全消除了對有狀態元件的需求,或者需要追蹤與資源無關的應用程式的某種狀態。 例如,讓我們採用確認對話方塊模式。您通常最終要做的是,您有一個本地記憶體狀態(如果它是開啟的),並根據該狀態將其顯示給使用者。在 HTMX 中,狀態 **IS THE HTML** 意味著當您按一下開啟模式時,您 **GET** `tasks/{taskId}/confirm-delete` 並將回應 HTML 嵌入到 DOM 中。當它被刪除時,您就完全刪除了模式和任務!這以一種獨特且極其簡單的方式解決了上述所有問題,您不需要: - 追蹤狀態 - 知道如何渲染對話框 - 記錄API - 檢查使用者是否可以刪除任務(在前端) - 您的後端應用程式始終負責 - 您可以獲得更好的安全性,因為您不會向瀏覽器發送不相關的資料並竊取敏感資訊 - 你會得到更好的表現 __*最重要的是,您可以讓您的應用程式保持簡單,只有在解決使用者問題時才允許複雜性!*__ 您只需指示 HTMX 從何處獲取對話框以及將其放置在何處,一切就完成了! ``` <!-- the delete button --> @if ($chirp->user->is(auth()->user())) <form> @csrf @method('delete') <x-dropdown-link :component="'button'" type="submit" hx-get="{{ route('chirps.confirm-destroy', $chirp) }}" hx-swap="beforeend" hx-target="closest .chirp" > {{ __('Delete') }} </x-dropdown-link> </form> @endif <!-- the dialog template --> <div class="modal fixed z-10 inset-0 overflow-y-auto flex justify-center items-center bg-black bg-opacity-50" style="backdrop-filter: blur(14px);"> <div class="bg-white rounded p-6"> <h2 class="text-xl border-b pb-2 mb-2">Confirm Action</h2> <p>Are you sure you want to delete this chirp?</p> <div class="flex justify-end mt-4 gap-4"> <x-secondary-button _="on click remove closest .modal" > Cancel </x-secondary-button> <form> @csrf <x-danger-button hx-delete="{{route('chirps.destroy', $chirp)}}" hx-target="closest .chirp" hx-swap="delete"> Delete </x-danger-button> </form> </div> </div> </div> ``` _這個範例來自我的 [HTMX with Laravel] 教學(https://dev.to/turculaurentiu91/laravel-htmx--g0n) ,請看!_ 就像這樣,當我們單擊刪除按鈕時,我們指示 HTMX 對 `chirps/{chirp}/confirm-destroy` 執行 **GET** 請求,並將結果 HTML 放在最接近的父級 `< 之前div class="chirp">` 結束(在底部)。在刪除對話方塊中,當使用者確認時,我們指示 HTMX 對 `chirps/{chirp}` 端點執行 **DELETE** 請求,成功後,我們刪除具有 `chirp` 類別的最接近的父級。 ## 結論 在不斷發展的 Web 開發領域,看到 HTMX 等倡導簡單性和回歸基礎的工具令人耳目一新。透過利用 HTML 和 HTTP 的強大功能,HTMX 允許開發人員建立動態 Web 應用程式,而無需傳統 JavaScript 框架的複雜性和開銷。 因此,下次您開始新專案或考慮重構現有專案時,請嘗試 HTMX。您可能會驚訝於用這麼少的錢就能取得如此大的成就。

從開源專案複製程式碼,算是偷竊嗎?

原文出處:https://dev.to/rjwignar/are-you-stealing-from-other-projects-4f0n ### 優秀的程式設計師抄襲;更優秀的程式設計師會偷竊嗎? > 優秀的藝術家臨摹;偉大的藝術家偷竊 > \- 巴勃羅·畢卡索 巴勃羅·畢卡索經常因說出上述引言而受到讚譽。我不會提供我自己對這句話的解釋,因為有興趣的人可以在網路上找到大量的解釋。然而,我經常想知道這句話如何應用於程式設計和開源開發。 ### 我們的程式設計知識真的是我們自己的嗎? 網路上有很多資源可以教您幾乎所有與程式設計相關的知識。我自己和我的許多同學幾乎所有的程式設計知識都是從教科書、線上資源/文件和 YouTube 教學中學到的。這些資源教會了我們今天擁有並應用的程式設計知識,但是所有這些知識都被盜了嗎?如果您從數千人觀看的 YouTube 教程中學會了編寫第一個“Hello World”程序,您是否在竊取程式碼?影片上傳者也學會使用外部資源編寫「Hello World」程式的可能性有多大?上傳者的知識被偷了嗎? 我不能說這些知識是否被盜,但我相信這種知識對於我們建立和擴展我們的技能是必要的。沒有人能夠知道每一個完美的實現,或是為每個專案編寫每一行程式碼。 ### 開源軟體是為使用而生的! 開源軟體的存在不應該被忽視,開源軟體是用來使用的!如果開源專案提供了您需要的功能,那麼當其他人為您精心完成這些功能時,為什麼還要自己實現這些功能呢?只要該庫得到積極維護並滿足您的需要,您就應該使用和研究開源庫。如果您發現任何錯誤、問題或缺少的功能,請嘗試建立自己的解決方案並為該專案做出貢獻,使其對每個人都更好!同樣,如果開源程式庫提供了您需要的功能,但您無法整合該程式庫,請以開源專案為靈感,在您自己的專案中實現該功能。 ### 從其他專案中獲取靈感 在我之前的[關於程式碼閱讀的部落格文章](https://dev.to/rjwignar/code-reading-i7h)中,我閱讀了Docusaurus 的程式碼庫來研究該專案如何為受保護的程式碼區塊實現語法突出顯示。我的研究告訴我,Docusaurus 實際上使用第三方函式庫 [Prism-React-Renderer](https://github.com/FormidableLabs/prism-react-renderer) 來提供語法突出顯示。這些知識很有用,因為我想在我的 Markdown 到 HTML 轉換器 [ctil](https://github.com/rjwignar/ctil) 新增語法突出顯示,但不想從頭開始實現該功能。雖然我無法在自己的專案中使用 Prism React Renderer,但研究 Docusaurus 給了我找到一個我可以使用的開源程式庫的想法。 ### 使用highlight.js 進行語法高亮顯示 在搜尋第三方語法螢光筆時,我找到了 [highlight.js](https://highlightjs.org/)。 ctil 將文字(`.txt`)和 Markdown (`.md`)轉換為生成的 HTML(`.html`)文件,因此我希望生成的 HTML 文件支援語法突出顯示。透過使用內容分發網路(CDN),highlight.js 可以用作 HTML 標籤,因此我可以透過將以下行新增至產生的 HTML 檔案來新增highlight.js: ``` <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script> <script>hljs.highlightAll();</script> ``` 透過這些行,我能夠[加入語法突出顯示](https://github.com/rjwignar/ctil/commit/c597f05724b60731e129aead33f1c3017a99ec17): ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k74q82mbi46fbbqupbri.png) ### 與 Docusaurus 方法的比較 在我的[上一篇部落格文章](https://dev.to/rjwignar/code-reading-i7h)中,我描述了 Docusaurus 如何使用 Prism React Renderer 新增語法突出顯示。與 Docusaurus 一樣,我使用了第三方函式庫highlight.js 來加入語法突出顯示。然而,在 Docusaurus 中新增和修改了設定檔以設定 Prism React Renderer,並透過使用「<Highlight />」元件加入了語法突出顯示。 Prism React Renderer 還提供了使用者可以在其專案中配置的突出顯示主題。對於我的專案,只需將highlight.js 加入到生成的 HTML 文件中,作為要透過 CDN 傳送的 HTML 標籤。現在我對基本的語法突出顯示感到滿意,所以我不關心有一個特定的突出顯示主題。透過 CDN 使用highlight.js 的一個缺點是,如果使用者在線,語法突出顯示可能無法運作。將來我可能會將highlight.js加入到專案本身中,這樣語法突出顯示就可以離線工作。 ### 下一步。 此功能仍在開發中。在目前迭代中,html 用作 `<code>...</code>` 區塊的預設語言類別。目前這是可以接受的,但此解決方案將忽略原始 Markdown 文件中的任何語言類設定。我希望 ctil 解析 Markdown 文件中的語言標籤,以確定使用哪種語言進行突出顯示。這將是未來需要解決的問題。有興趣的人可以在[此處](https://github.com/rjwignar/ctil/issues/11)找到問題。 ### 那麼從開源專案複製程式碼算不算偷竊? 只要專案許可證允許複製,並且您遵循專案許可證的要求,您就不會竊取。同樣,我認為從開源專案中尋找靈感並不是偷竊。

44 個 React 前端面試問題

原文出處:https://dev.to/m_midas/44-react-frontend-interview-questions-2o63 ## 介紹 在面試 React 前端開發人員職位時,為技術問題做好充分準備至關重要。 React 已經成為建立使用者介面最受歡迎的 JavaScript 程式庫之一,雇主通常專注於評估候選人對 React 核心概念、最佳實踐和相關技術的理解。在本文中,我們將探討 React 前端開發人員面試期間常見問題的完整清單。透過熟悉這些問題及其答案,您可以增加成功的機會並展示您在 React 開發方面的熟練程度。因此,讓我們深入探討您應該準備好在 React 前端開發人員面試中解決的關鍵主題。 ![](https://media.giphy.com/media/AYECTMLNS4o67dCoeY/giphy.gif) ### 1.你知道哪些React hooks? - `useState`:用於管理功能元件中的狀態。 - `useEffect`:用於在功能元件中執行副作用,例如取得資料或訂閱事件。 - `useContext`:用於存取功能元件內的 React 上下文的值。 - `useRef`:用於建立對跨渲染持續存在的元素或值的可變引用。 - `useCallback`:用於記憶函數以防止不必要的重新渲染。 - `useMemo`:用於記憶值,透過快取昂貴的計算來提高效能。 - `useReducer`:用於使用reducer函數管理狀態,類似於Redux的工作方式。 - `useLayoutEffect`:與 useEffect 類似,但效果在所有 DOM 變更後同步運作。 這些鉤子提供了強大的工具來管理狀態、處理副作用以及重複使用 React 功能元件中的邏輯。 [了解更多](https://react.dev/reference/react) ### 2.什麼是虛擬 DOM? 虛擬 DOM 是 React 中的一個概念,其中建立實際 DOM(文件物件模型)的輕量級虛擬表示並將其儲存在記憶體中。它是一種用於優化 Web 應用程式效能的程式設計技術。 當 React 元件的資料或狀態發生變更時,虛擬 DOM 會被更新,而不是直接操作真實 DOM。然後,虛擬 DOM 計算元件的先前狀態和更新狀態之間的差異,稱為「比較」過程。 一旦辨識出差異,React 就會有效地僅更新真實 DOM 的必要部分以反映變更。這種方法最大限度地減少了實際 DOM 操作的數量,並提高了應用程式的整體效能。 透過使用虛擬 DOM,React 提供了一種建立動態和互動式使用者介面的方法,同時確保最佳效率和渲染速度。 ### 3. 如何渲染元素陣列? 要渲染元素陣列,可以使用“map()”方法迭代該陣列並傳回一個新的 React 元素陣列。 ``` const languages = [ "JavaScript", "TypeScript", "Python", ]; function App() { return ( <div> <ul>{languages.map((language) => <li>{language}</li>)}</ul> </div> ); } ``` [了解更多](https://react.dev/learn/rendering-lists) ### 4. 受控元件和非受控元件有什麼不同? 受控元件和非受控元件之間的區別在於**它們如何管理和更新其狀態**。 受控元件是狀態由 React 控制的元件。元件接收其當前值並透過 props 更新它。當值改變時它也會觸發回調函數。這意味著該元件不儲存其自己的內部狀態。相反,父元件管理該值並將其傳遞給受控元件。 ``` import { useState } from 'react'; function App() { const [value, setValue] = useState(''); return ( <div> <h3>Controlled Component</h3> <input name="name" value={name} onChange={(e) => setValue(e.target.value)} /> <button onClick={() => console.log(value)}>Get Value</button> </div> ); } ``` 另一方面,不受控制的元件使用 refs 或其他方法在內部管理自己的狀態。它們獨立儲存和更新狀態,不依賴 props 或回呼。父元件對不受控元件的狀態控制較少。 ``` import { useRef } from 'react'; function App() { const inputRef = useRef(null); return ( <div className="App"> <h3>Uncontrolled Component</h3> <input type="text" name="name" ref={inputRef} /> <button onClick={() => console.log(inputRef.current.value)}>Get Value</button> </div> ); } ``` [了解更多](https://react.dev/learn/sharing-state- Between-components#driven-and-uncontrol-components) ### 5. 基於類別的 React 元件和函數式 React 元件有什麼不同? 基於類別的元件和函數式元件之間的主要區別在於**它們的定義方式以及它們使用的語法。** 基於類別的元件被定義為 ES6 類別並擴展了 `React.Component` 類別。他們使用「render」方法傳回定義元件輸出的 JSX (JavaScript XML)。類別元件可以透過「this.state」和「this.setState()」存取元件生命週期方法和狀態管理。 ``` class App extends React.Component { state = { value: 0, }; handleAgeChange = () => { this.setState({ value: this.state.value + 1 }); }; render() { return ( <> <p>Value is {this.state.value}</p> <button onClick={this.handleAgeChange}> Increment value </button> </> ); } } ``` 另一方面,函數元件被定義為簡單的 JavaScript 函數。他們接受 props 作為參數並直接返回 JSX。功能元件無權存取生命週期方法或狀態。然而,隨著 React 16.8 中 React Hooks 的引入,功能元件現在可以管理狀態並使用其他功能,例如上下文和效果。 ``` import { useState } from 'react'; const App = () => { const [value, setValue] = useState(0); const handleAgeChange = () => { setValue(value + 1); }; return ( <> <p>Value is {value}</p> <button onClick={handleAgeChange}> Increment value </button> </> ); } ``` 一般來說,功能元件被認為更簡單、更容易閱讀和測試。建議盡可能使用函數式元件,除非有特定需要基於類別的元件。 ### 6. 元件的生命週期方法有哪些? 生命週期方法是一種掛鉤元件生命週期不同階段的方法,可讓您在特定時間執行特定程式碼。 以下是主要生命週期方法的清單: 1. `constructor`:這是建立元件時呼叫的第一個方法。它用於初始化狀態和綁定事件處理程序。在功能元件中,您可以使用“useState”鉤子來實現類似的目的。 2. `render`:此方法負責渲染 JSX 標記並傳回螢幕上要顯示的內容。 3. `componentDidMount`:元件在 DOM 中渲染後立即呼叫該方法。它通常用於初始化任務,例如 API 呼叫或設定事件偵聽器。 4. `componentDidUpdate`:當元件的 props 或 state 改變時呼叫該方法。它允許您執行副作用、根據更改更新元件或觸發其他 API 呼叫。 5. `componentWillUnmount`:在元件從 DOM 刪除之前呼叫此方法。它用於清理在`componentDidMount`中設定的任何資源,例如刪除事件偵聽器或取消計時器。 一些生命週期方法,例如“componentWillMount”、“componentWillReceiveProps”和“componentWillUpdate”,已被棄用或替換為替代方法或掛鉤。 至於“this”,它指的是類別元件的當前實例。它允許您存取元件內的屬性和方法。在函數式元件中,不使用“this”,因為函數未綁定到特定實例。 ### 7. 使用 useState 有什麼特色? `useState` 傳回一個狀態值和一個更新它的函數。 ``` const [value, setValue] = useState('Some state'); ``` 在初始渲染期間,傳回的狀態與作為第一個參數傳遞的值相符。 `setState` 函數用於更新狀態。它採用新的狀態值作為參數,並**對元件的重新渲染進行排隊**。 `setState` 函數也可以接受回呼函數作為參數,該函數將先前的狀態值作為參數。 [了解更多](https://react.dev/reference/react/useState) ### 8. 使用 useEffect 有什麼特別之處? `useEffect` 鉤子可讓您在功能元件中執行副作用。 稱為 React 渲染階段的功能元件的主體內部不允許突變、訂閱、計時器、日誌記錄和其他副作用。這可能會導致用戶介面中出現令人困惑的錯誤和不一致。 相反,建議使用 useEffect。傳遞給 useEffect 的函數將在渲染提交到螢幕後執行,或者如果您傳遞一組依賴項作為第二個參數,則每次依賴項之一發生變更時都會呼叫該函數。 ``` useEffect(() => { console.log('Logging something'); }, []) ``` [了解更多](https://react.dev/reference/react/useEffect) ### 9. 如何追蹤功能元件的卸載? 通常,「useEffect」會建立在元件離開畫面之前需要清理或重設的資源,例如訂閱或計時器辨識碼。 為了做到這一點,傳遞給`useEffect`的函數可以傳回一個**清理函數**。清理函數在元件從使用者介面刪除之前執行,以防止記憶體洩漏。此外,如果元件渲染多次(通常是這種情況),則在執行下一個效果之前會清除上一個效果。 ``` useEffect(() => { function handleChange(value) { setValue(value); } SomeAPI.doFunction(id, handleChange); return function cleanup() { SomeAPI.undoFunction(id, handleChange); }; }) ``` ### 10. React 中的 props 是什麼? Props 是從父元件傳遞給元件的資料。道具 是唯讀的,無法更改。 ``` // Parent component const Parent = () => { const data = "Hello, World!"; return ( <div> <Child data={data} /> </div> ); }; // Child component const Child = ({ data }) => { return <div>{data}</div>; }; ``` [了解更多](https://react.dev/learn/passing-props-to-a-component) ### 11. 什麼是狀態管理器?您曾與哪些狀態管理器合作過或認識哪些狀態管理器? 狀態管理器是幫助管理應用程式狀態的工具或程式庫。它提供了一個集中式儲存或容器來儲存和管理可由應用程式中的不同元件存取和更新的資料。 狀態管理器可以解決幾個問題。首先,將資料和與其相關的邏輯與元件分開是一個很好的做法。其次,當使用本機狀態並在元件之間傳遞它時,由於元件可能存在深層嵌套,程式碼可能會變得複雜。透過擁有全域存儲,我們可以存取和修改來自任何元件的資料。 除了 React Context,Redux 或 MobX 通常用作狀態管理庫。 [了解更多](https://mobx.js.org/README.html) [了解更多](https://redux-toolkit.js.org/) ### 12. 在什麼情況下可以使用本地狀態,什麼時候應該使用全域狀態? 如果本機狀態僅在一個元件中使用且不打算將其傳遞給其他元件,則建議使用本機狀態。本地狀態也用在表示清單中單一專案的元件中。但是,如果元件分解涉及嵌套元件且資料沿層次結構傳遞,則最好使用全域狀態。 ### 13. Redux中的reducer是什麼,它需要哪些參數? 減速器是一個純函數,它將狀態和操作作為參數。在減速器內部,我們追蹤接收到的操作的類型,並根據它修改狀態並傳回一個新的狀態物件。 ``` export default function appReducer(state = initialState, action) { // The reducer normally looks at the action type field to decide what happens switch (action.type) { // Do something here based on the different types of actions default: // If this reducer doesn't recognize the action type, or doesn't // care about this specific action, return the existing state unchanged return state } } ``` [了解更多](https://redux.js.org/tutorials/fundamentals/part-3-state-actions-reducers) ### 14. 什麼是操作以及如何更改 Redux 中的狀態? Action 是一個簡單的 JavaScript 物件,必須有一個字段 一種。 ``` { type: "SOME_TYPE" } ``` 您也可以選擇新增一些資料作為**有效負載**。為了 改變狀態,需要呼叫我們傳遞給它的調度函數 行動 ``` { type: "SOME_TYPE", payload: "Any payload", } ``` [了解更多](https://redux.js.org/tutorials/fundamentals/part-3-state-actions-reducers) ### 15. Redux 實作了哪一種模式? Redux 實作了 **Flux 模式**,這是應用程式可預測的狀態管理模式。它透過引入單向資料流和應用程式狀態的集中儲存來幫助管理應用程式的狀態。 [了解更多](https://www.newline.co/fullstack-react/30-days-of-react/day-18/#:~:text=Flux%20is%20a%20pattern%20for,default% 20method %20用於%20處理%20資料。) ### 16. Mobx 實作哪一種模式? Mobx 實作了**觀察者模式**,也稱為發布-訂閱模式。 [了解更多](https://www.patterns.dev/posts/observer-pattern) ### 17. 使用 Mobx 的特徵是什麼? Mobx 提供了「observable」和「compulated」等裝飾器來定義可觀察狀態和反應函數。以action修飾的動作用於修改狀態,確保追蹤所有變更。 Mobx 還提供自動依賴追蹤、不同類型的反應、對反應性的細粒度控制,以及透過 mobx-react 套件與 React 無縫整合。總體而言,Mobx 透過根據可觀察狀態的變化自動執行更新過程來簡化狀態管理。 ### 18.如何存取Mobx狀態下的變數? 您可以透過使用「observable」裝飾器將變數定義為可觀察來存取狀態中的變數。這是一個例子: ``` import { observable, computed } from 'mobx'; class MyStore { @observable myVariable = 'Hello Mobx'; @computed get capitalizedVariable() { return this.myVariable.toUpperCase(); } } const store = new MyStore(); console.log(store.capitalizedVariable); // Output: HELLO MOBX store.myVariable = 'Hi Mobx'; console.log(store.capitalizedVariable); // Output: HI MOBX ``` 在此範例中,使用“observable”裝飾器將“myVariable”定義為可觀察物件。然後,您可以使用“store.myVariable”存取該變數。對「myVariable」所做的任何變更都會自動觸發相關元件或反應的更新。 [了解更多](https://mobx.js.org/actions.html) ### 19.Redux 和 Mobx 有什麼差別? Redux 是一個更簡單、更固執己見的狀態管理庫,遵循嚴格的單向資料流並促進不變性。它需要更多的樣板程式碼和顯式更新,但與 React 具有出色的整合。 另一方面,Mobx 提供了更靈活、更直觀的 API,且樣板程式碼更少。它允許您直接修改狀態並自動追蹤更改以獲得更好的性能。 Redux 和 Mobx 之間的選擇取決於您的特定需求和偏好。 ### 20.什麼是 JSX? 預設情況下,以下語法用於在 React 中建立元素。 ``` const someElement = React.createElement( 'h3', {className: 'title__value'}, 'Some Title Value' ); ``` 但我們已經習慣這樣看 ``` const someElement = ( <h3 className='title__value'>Some Title Value</h3> ); ``` 這正是標記所謂的 jsx。這是一種語言的擴展 簡化對程式碼和開發的認知 [了解更多](https://react.dev/learn/writing-markup-with-jsx#jsx-putting-markup-into-javascript) ### 21.什麼是道具鑽探? Props 鑽取是指透過多層嵌套元件傳遞 props 的過程,即使某些中間元件不直接使用這些 props。這可能會導致程式碼結構複雜且繁瑣。 ``` // Parent component const Parent = () => { const data = "Hello, World!"; return ( <div> <ChildA data={data} /> </div> ); }; // Intermediate ChildA component const ChildA = ({ data }) => { return ( <div> <ChildB data={data} /> </div> ); }; // Leaf ChildB component const ChildB = ({ data }) => { return <div>{data}</div>; }; ``` 在此範例中,「data」屬性從 Parent 元件傳遞到 ChildA,然後從 ChildA 傳遞到 ChildB,即使 ChildA 不會直接使用該屬性。當存在許多層級的嵌套或當元件樹中更靠下的元件需要存取資料時,這可能會成為問題。它會使程式碼更難維護和理解。 可以透過使用其他模式(如上下文或狀態管理庫(如 Redux 或 MobX))來緩解 Props 鑽探。這些方法允許元件存取資料,而不需要透過每個中間元件傳遞 props。 ### 22. 如何有條件地渲染元素? 您可以使用任何條件運算符,包括三元。 ``` return ( <div> {isVisible && <span>I'm visible!</span>} </div> ); ``` ``` return ( <div> {isOnline ? <span>I'm online!</span> : <span>I'm offline</span>} </div> ); ``` ``` if (isOnline) { element = <span>I'm online!</span>; } else { element = <span>I'm offline</span>; } return ( <div> {element} </div> ); ``` [了解更多](https://react.dev/learn/conditional-rendering) ### 23. useMemo 的用途是什麼?它是如何運作的? `useMemo` 用於緩存和記憶 計算結果。 傳遞建立函數和依賴項陣列。只有當任何依賴項的值發生變更時,`useMemo` 才會重新計算記憶值。此優化有助於避免 每次渲染都需要昂貴的計算。 使用第一個參數,函數接受執行計算的回調,使用第二個依賴項陣列,僅當至少一個依賴項發生變更時,該函數才會重新執行計算。 ``` const memoValue = useMemo(() => computeFunc(paramA, paramB), [paramA, paramB]); ``` [了解更多](https://react.dev/reference/react/useMemo) ### 24. useCallback 的用途是什麼?它是如何運作的? `useCallback` 掛鉤將傳回回呼的記憶版本,僅當依賴項之一的值發生變更時,該版本才會變更。 當將回調傳遞給依賴連結相等性來防止不必要的渲染的最佳化子元件時,這非常有用。 ``` const callbackValue = useCallback(() => computeFunc(paramA, paramB), [paramA, paramB]); ``` [了解更多](https://react.dev/reference/react/useCallback) ### 25. useMemo 和 useCallback 有什麼不同? 1. `useMemo` 用於儲存計算結果,而 `useCallback` 用於儲存函數本身。 2. `useMemo` 快取計算值,如果依賴項沒有改變,則在後續渲染時傳回它。 3. `useCallback` 快取函數本身並傳回相同的實例,除非相依性發生變更。 ### 26.什麼是 React Context? React Context 是一項功能,它提供了一種透過元件樹傳遞資料的方法,而無需在每個層級手動傳遞 props。它允許您建立一個全域狀態,樹中的任何元件都可以存取該狀態,無論其位置如何。當您需要在未透過 props 直接連接的多個元件之間共用資料時,上下文就非常有用。 React Context API 由三個主要部分組成: 1. `createContext`:此函數用於建立一個新的上下文物件。 2. `Context.Provider`:該元件用於向上下文提供值。它包裝了需要存取該值的元件。 3. `Context.Consumer` 或 `useContext` 鉤子:此元件或鉤子用於使用上下文中的值。它可以在上下文提供者內的任何元件中使用。 透過使用 React Context,您可以避免道具鑽探(透過多個層級的元件傳遞道具)並輕鬆管理更高層級的狀態,使您的程式碼更有組織性和效率。 [了解更多](https://react.dev/learn/passing-data-deeply-with-context) ### 27. useContext 的用途是什麼?它是如何運作的? 在典型的 React 應用程式中,資料使用 props 從上到下(從父元件到子元件)傳遞。但這樣的使用方法對於某些類型的道具來說可能過於繁瑣 (例如,所選語言、UI 主題),必須傳遞給應用程式中的許多元件。上下文提供了一種在元件之間共享此類資料的方法,而無需明確傳遞 props 樹的每一層。 呼叫 useContext 的元件將始終在以下情況下重新渲染: 上下文值發生變化。如果重新渲染元件的成本很高,您可以使用記憶來優化它。 ``` const App = () => { const theme = useContext(ThemeContext); return ( <div style={{ color: theme.palette.primary.main }}> Some div </div> ); } ``` [了解更多](https://react.dev/reference/react/useContext) ### 28. useRef 的用途是什麼?它是如何運作的? `useRef` 傳回一個可修改的 ref 物件,一個屬性。其中的當前值由傳遞的參數初始化。傳回的物件將在元件的整個生命週期內持續存在,並且不會因渲染而改變。 通常的用例是以命令式存取後代 風格。 IE。使用 ref,我們可以明確引用 DOM 元素。 ``` const App = () => { const inputRef = useRef(null); const buttonClick = () => { inputRef.current.focus(); } return ( <> <input ref={inputRef} type="text" /> <button onClick={buttonClick}>Focus on input tag</button> </> ) } ``` [了解更多](https://react.dev/reference/react/useRef) ### 29. 什麼是 React.memo()? `React.memo()` 是一個高階元件。如果您的元件始終使用不變的 props 渲染相同的內容,您可以將其包裝在「React.memo()」呼叫中,以在某些情況下提高效能,從而記住結果。這意味著 React 將使用上次渲染的結果,避免重新渲染。 `React.memo()` 只影響 props 的變更。如果一個功能元件被包裝在 React.memo 中並使用 useState、useReducer 或 useContext,那麼當狀態或上下文發生變化時,它將重新渲染。 ``` import { memo } from 'react'; const MemoComponent = memo(MemoComponent = (props) => { // ... }); ``` [了解更多](https://react.dev/reference/react/memo) ### 30.React Fragment是什麼? 從元件傳回多個元素是 React 中的常見做法。片段可讓您形成子元素列表,而無需在 DOM 中建立不必要的節點。 ``` <> <OneChild /> <AnotherChild /> </> // or <React.Fragment> <OneChild /> <AnotherChild /> </React.Fragment> ``` [了解更多](https://react.dev/reference/react/Fragment) ### 31.什麼是 React Reconciliation? 協調是一種 React 演算法,用於區分一棵元素樹與另一棵元素樹,以確定需要替換的部分。 協調是我們過去所說的虛擬 DOM 背後的演算法。這個定義聽起來是這樣的:當你渲染一個 React 應用程式時,描述該應用程式的元素樹是在保留的記憶體中產生的。然後這棵樹被包含在渲染環境中——例如,瀏覽器應用程式,它被翻譯成一組 DOM 操作。當應用程式狀態更新時,會產生一棵新樹。將新樹與前一棵樹進行比較,以便準確計算並啟用重繪更新的應用程式所需的操作。 [了解更多](https://react.dev/learn/preserving-and-resetting-state) ### 32.為什麼使用map()時需要列表中的鍵? 這些鍵可幫助 React 確定哪些元素已更改, 新增或刪除。必須指定它們以便 React 可以匹配 隨著時間的推移陣列元素。選擇鍵的最佳方法是使用能夠清楚區分清單專案與其鄰居的字串。大多數情況下,您將使用資料中的 ID 作為金鑰。 ``` const languages = [ { id: 1, lang: "JavaScript", }, { id: 2, lang: "TypeScript", }, { id: 3, lang: "Python", }, ]; const App = () => { return ( <div> <ul>{languages.map((language) => ( <li key={`${language.id}_${language.lang}`}>{language.lang}</li> ))} </ul> </div> ); } ``` [了解更多](https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key) ### 33. 如何在 Redux Thunk 中處理非同步操作? 要使用 Redux Thunk,您需要將其作為中間件導入。動作建立者不僅應該傳回一個物件,還應該傳回以調度為參數的函數。 ``` export const addUser = ({ firstName, lastName }) => { return dispatch => { dispatch(addUserStart()); } axios.post('https://jsonplaceholder.typicode.com/users', { firstName, lastName, completed: false }) .then(res => { dispatch(addUserSuccess(res.data)); }) .catch(error => { dispatch(addUserError(error.message)); }) } ``` [了解更多](https://redux.js.org/usage/writing-logic-thunks) ### 34.如何追蹤功能元件中物件欄位的變化? 為此,您需要使用“useEffect”掛鉤並將物件的欄位作為依賴項陣列傳遞。 ``` useEffect(() => { console.log('Changed!') }, [obj.someField]) ``` ### 35.如何存取DOM元素? 引用是使用 React.createRef() 或 useRef() 鉤子建立的,並透過 ref 屬性附加到 React 元素。透過存取已建立的引用,我們可以使用「ref.current」來存取 DOM 元素。 ``` const App = () => { const myRef = useRef(null); const handleClick = () => { console.log(myRef.current); // Accessing the DOM element }; return ( <div> <input type="text" ref={myRef} /> <button onClick={handleClick}>Click Me</button> </div> ); } export default App; ``` ### 36.什麼是自訂鉤子? 自訂鉤子是一個允許您在不同元件之間重複使用邏輯的功能。它是一種封裝可重複使用邏輯的方法,以便可以在多個元件之間輕鬆共用和重複使用。自訂掛鉤是通常以 **use ** 開頭的函數,並且可以根據需要呼叫其他掛鉤。 [了解更多](https://react.dev/learn/reusing-logic-with-custom-hooks) ### 37.什麼是公共API? 在索引檔案的上下文中,公共 API 通常是指向外部模組或元件公開並可存取的介面或函數。 以下是表示公共 API 的索引檔案的程式碼範例: ``` // index.js export function greet(name) { return `Hello, ${name}!`; } export function calculateSum(a, b) { return a + b; } ``` 在此範例中,index.js 檔案充當公共 API,其中導出函數“greet()”和“calculateSum()”,並且可以透過匯入它們從其他模組存取它們。其他模組可以導入並使用這些函數作為其實現的一部分: ``` // main.js import { greet, calculateSum } from './index.js'; console.log(greet('John')); // Hello, John! console.log(calculateSum(5, 3)); // 8 ``` 透過從索引檔案匯出特定函數,我們定義了模組的公共 API,允許其他模組使用這些函數。 ### 38. 建立自訂鉤子的規則是什麼? 1. 鉤子名稱以「use」開頭。 2. 如果需要,使用現有的鉤子。 3. 不要有條件地呼叫鉤子。 4. 將可重複使用邏輯提取到自訂掛鉤中。 5. 自訂hook必須是純函數。 6. 自訂鉤子可以傳回值或其他鉤子。 7. 描述性地命名自訂掛鉤。 [了解更多](https://react.dev/learn/reusing-logic-with-custom-hooks) ### 39.什麼是SSR(伺服器端渲染)? 伺服器端渲染(SSR)是一種用於在伺服器上渲染頁面並將完整渲染的頁面傳送到客戶端進行顯示的技術。它允許伺服器產生網頁的完整 HTML 標記(包括其動態內容),並將其作為對請求的回應傳送到客戶端。 在傳統的用戶端渲染方法中,用戶端接收最小的 HTML 頁面,然後向伺服器發出額外的資料和資源請求,這些資料和資源用於在客戶端渲染頁面。這可能會導致初始頁面載入時間變慢,並對搜尋引擎優化 (SEO) 產生負面影響,因為搜尋引擎爬蟲很難對 JavaScript 驅動的內容建立索引。 透過 SSR,伺服器透過執行必要的 JavaScript 程式碼來產生最終的 HTML 來負責渲染網頁。這意味著客戶端從伺服器接收完全呈現的頁面,從而減少了額外資源請求的需要。 SSR 縮短了初始頁面載入時間,並允許搜尋引擎輕鬆索引內容,從而實現更好的 SEO。 SSR 通常用於框架和函式庫中,例如用於 React 的 Next.js 和用於 Vue.js 的 Nuxt.js,以啟用伺服器端渲染功能。這些框架為您處理伺服器端渲染邏輯,讓實作 SSR 變得更加容易。 ### 40.使用SSR有什麼好處? 1. **改進初始載入時間**:SSR 允許伺服器將完全渲染的 HTML 頁面傳送到客戶端,從而減少客戶端所需的處理量。這可以縮短初始載入時間,因為使用者可以更快地看到完整的頁面。 2. **SEO友善**:搜尋引擎可以有效地抓取和索引SSR頁面的內容,因為完全渲染的HTML在初始回應中可用。這提高了搜尋引擎的可見度並有助於更好的搜尋排名。 3. **可存取性**:SSR 確保禁用 JavaScript 或使用輔助技術的使用者可以存取內容。透過在伺服器上產生 HTML,SSR 為所有使用者提供可靠且易於存取的使用者體驗。 4. **低頻寬環境下的效能**:SSR減少了客戶端需要下載的資料量,有利於低頻寬或高延遲環境下的使用者。這對於行動用戶或網路連線速度較慢的用戶尤其重要。 雖然 SSR 提供了這些優勢,但值得注意的是,與客戶端渲染方法相比,它可能會帶來更多的伺服器負載和維護複雜性。應仔細考慮快取、可擴展性和伺服器端渲染效能最佳化等因素。 ### 41.你知道Next.js的主要功能有哪些? 1. `getStaticProps`:此方法用於在建置時取得資料並將頁面預先渲染為靜態 HTML。它確保資料在建置時可用,並且不會因後續請求而更改。 ``` export async function getStaticProps() { const res = await fetch('https://api.example.com/data'); const data = await res.json(); return { props: { data } }; } ``` 2. `getServerSideProps`:此方法用於在每個請求上取得資料並在伺服器上預先渲染頁面。當您需要取得可能經常變更或特定於使用者的資料時,可以使用它。 ``` export async function getServerSideProps() { const res = await fetch('https://api.example.com/data'); const data = await res.json(); return { props: { data } }; } ``` 3. `getStaticPaths`:此方法在動態路由中使用,用於指定建置時應預先渲染的路徑清單。它通常用於獲取帶有參數的動態路由的資料。 ``` export async function getStaticPaths() { const res = await fetch('https://api.example.com/posts'); const posts = await res.json(); const paths = posts.map((post) => ({ params: { id: post.id } })); return { paths, fallback: false }; } ``` [了解更多](https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating) ### 42.什麼是 Linters? Linters 是用來檢查原始程式碼是否有潛在錯誤、錯誤、風格不一致和可維護性問題的工具。它們可幫助執行編碼標準並確保整個程式碼庫的程式碼品質和一致性。 Linters 的工作原理是掃描原始程式碼並將其與一組預先定義的規則或指南進行比較。這些規則可以包括語法和格式約定、最佳實踐、潛在錯誤和程式碼異味。當 linter 發現違反規則時,它會產生警告或錯誤,突出顯示需要注意的特定行或多行程式碼。 使用 linter 可以帶來幾個好處: 1. **程式碼品質**:Linter 有助於辨識和防止潛在的錯誤、程式碼異味和反模式,從而提高程式碼品質。 2. **一致性**:Linter 強制執行編碼約定和風格指南,確保整個程式碼庫的格式和程式碼結構一致,即使多個開發人員正在處理同一個專案時也是如此。 3. **可維護性**:透過儘早發現問題並促進良好的編碼實踐,linter 有助於程式碼的可維護性,使程式碼庫更容易理解、修改和擴展。 4. **效率**:Linter 可以透過自動化程式碼審查流程並在常見錯誤在開發或生產過程中引起問題之前捕獲它們來節省開發人員的時間。 一些流行的 linter 包括用於 JavaScript 的 ESLint 以及用於 CSS 和 Sass 的 Stylelint。 [了解更多](https://eslint.org/docs/latest/use/getting-started) ### 43.你知道哪些 React 架構解決方案? 有多種用於建立 React 專案的架構解決方案和模式。一些受歡迎的包括: 1. **MVC(模型-視圖-控制器)**:MVC 是一種傳統的架構模式,它將應用程式分為三個主要元件 - 模型、視圖和控制器。 React 可以在 View 層中使用來渲染 UI,而其他程式庫或框架可以用於 Model 和 Controller 層。 2. **Flux**:Flux是Facebook專門針對React應用程式所推出的應用架構。它遵循單向資料流,其中資料沿著單一方向流動,從而更容易理解和除錯應用程式的狀態變更。 3. **原子設計**:原子設計並不是React特有的,而是將UI分割成更小、可重複使用元件的設計方法。它鼓勵建立小型、獨立且可以組合以建立更複雜的 UI 的元件。 4. **容器和元件模式**:此模式將表示(元件)與邏輯和狀態管理(容器)分開。元件負責渲染 UI,而容器則處理業務邏輯和狀態管理。 5. **功能切片設計**:它是一種用於組織和建構 React 應用程式的現代架構方法。它旨在透過根據功能或模組劃分應用程式程式碼庫來解決可擴展性、可維護性和可重用性的挑戰。 ### 44.什麼是特徵切片設計? 它是一種用於組織和建立 React 應用程式的現代架構方法。它旨在透過根據功能或模組劃分應用程式程式碼庫來解決可擴展性、可維護性和可重用性的挑戰。 在功能切片設計中,應用程式的每個功能或模組都組織到一個單獨的目錄中,其中包含所有必要的元件、操作、reducers 和其他相關檔案。這有助於保持程式碼庫的模組化和隔離性,使其更易於開發、測試和維護。 功能切片設計促進了關注點的清晰分離,並將功能封裝在各個功能中。這允許不同的團隊或開發人員獨立地處理不同的功能,而不必擔心衝突或依賴性。 ![功能切片設計](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/amysbtftfjkuss87yu8v.png) **我強烈建議點擊“了解更多”按鈕以了解功能切片設計** [了解更多](https://dev.to/m_midas/feature-sliced-design-the-best-frontend-architecture-4noj) ## 了解更多 如果您還沒有閱讀過,我強烈建議您閱讀我關於前端面試問題的其餘文章。 https://dev.to/m_midas/52-frontend-interview-questions-javascript-59h6 https://dev.to/m_midas/41-frontend-interview-questions-css-4imc https://dev.to/m_midas/15-most-common-frontend-interview-questions-4njp ## 結論 總之,面試 React 前端開發人員職位需要對框架的核心概念、原理和相關技術有深入的了解。透過準備本文中討論的問題,您可以展示您的 React 知識並展示您建立高效且可維護的使用者介面的能力。請記住,不僅要專注於記住答案,還要理解基本概念並能夠清楚地解釋它們。 此外,請記住,面試不僅涉及技術方面,還旨在展示您解決問題的能力、溝通能力以及團隊合作能力。透過將技術專業知識與強大的整體技能相結合,您將具備在 React 前端開發人員面試中脫穎而出的能力,並在這個令人興奮且快速發展的領域找到您夢想的工作。 祝你好運!

給網頁工程師的 24 個強大資源 [HTML + CSS + JavaScript]

## 簡介 Web 開發的世界可能會因資源太多而令人不知所措。為了簡化這個過程,我列出了專為 Web 開發人員量身定制的 24 個最佳資源。 本指南涵蓋 HTML、CSS 和 JavaScript 的核心技術,旨在為初學者和專家提供有價值的工具和見解,以提高他們的 Web 開發技能。請探索這些精心挑選的資源,以幫助您在 Web 開發中脫穎而出。 原文出處:https://dev.to/swirl/24-best-resources-for-web-developers-html-css-javascript--2hog --- ## [Swirl](https://github.com/swirlai/swirl-search) [![Swirl v3 演示](https://i.ibb.co/ZBY1HXD/Swirl-v3-Demo-1-2.gif)](https://github.com/swirlai/swirl-search) 搜尋多個來源具有挑戰性。 Swirl 結合了您所有的資料庫、筆記、PDF、Jira、GitHub、向量資料庫、Discord、Slack、Teams Chat 等,並允許您搜尋它們。 允許您: - 產生答案的人工智慧摘要。 🤖 - 管理您的資料並建立知識庫。 📚 - 節省時間並提高工作效率。 ⏳ 請在 GitHub 上給 Swirl Search 一個 ⭐️。 💖 https://github.com/swirlai/swirl-search 在 GitHub 上給 Swirl ⭐ --- ## CSS 工具 #### 1. [CSS 漸變](https://cssgradient.io/) CSS Gradient 是一個可讓您為網站建立免費漸變背景的專案。 ![CSS 漸變](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y3pz3pttdz3mw73hfgd6.png) #### 2. [Colorhunt](https://colorhunt.co/) Colorhunt 為設計師和藝術家提供了很棒的調色板。 ![Colorhunt](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/36tgjp6atk0gbqvyrkof.png) #### 3. [CSS 技巧](https://css-tricks.com/) CSS Tricks 提供了有關級聯樣式表的一些最佳建議、提示、技巧和程式碼片段。 ![CSS 技巧](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9cpyxw7dh1st3u2t2lpd.png) #### 4. [Haikei 生成器](https://haikei.app/generators/) Haikei 是一款 Web 應用程式,可產生令人驚嘆的視覺內容 - 可與您的設計工具和工作流程一起使用。 ![Haikei 產生器](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u1iodm4kouyeo1fqaapi.png) #### 5. [FFFuel](https://fffuel.co/gggrain/) Fffuel 是一個顏色工具和免費 SVG 生成器的集合,用於漸變、圖案、紋理、形狀和背景。 ![FFFuel](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rtuapj8v11oy90wu63vl.png) #### 6. [SVG 背景](https://www.svgbackgrounds.com/) SVG 背景託管一系列可在您的網站上使用的 SVG 背景。 ![SVG 背景](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/snvajtzhfcdeij595okb.png) #### 7. [動畫背景](https://animatedbackgrounds.me/) 動畫背景託管各種動畫背景的程式碼片段,可用作網站的背景。 ![動畫背景](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ihajx942sr0a1hdjhpc9.png) #### 8. [Flowbite](https://flowbite.com/blocks/publisher/blog-templates/) Flowbite 提供了一組基於流行的 Tailwind CSS 框架的強大設計令牌和元件。 ![Flowbite](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k5vm5gt1eq8xp3v2sfeb.png) #### 9. [DaisyUI](https://daisyui.com/) DaisyUI 為 Tailwind CSS 新增了一組可自訂的顏色名稱,這些新顏色使用 CSS 變數作為值。 ![DaisyUI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ftt8w6hb86u053ou1jjr.png) --- ## HTML #### 10. [Quackit 的 HTML 範本](https://www.quackit.com/html/templates/) Quackit 提供了大量免費網站模板可供選擇。根據您的選擇,您可以從簡單或更高級的模板清單中進行選擇。 ![Quackit 的 HTML 範本](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rpck2niq9956wgdiknmq.png) --- ## 圖示 #### 11. [Devicon](https://devicon.dev/) Devicon 是一組代表程式語言、設計和開發工具的圖示。您可以將其用作字體或將 SVG 程式碼複製/貼上到您的專案中。 ![Devicon](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nuwk7f14xmmahc3l5368.png) #### 12. [Flaticon](https://www.flaticon.com/) 為您的專案下載免費圖示和貼紙 - 由設計師製作並為設計師製作的 PNG、SVG 等格式的圖像。 ![Flaticon](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/694zggooyig7digfrje6.png) --- ## 低程式碼工具 #### 13. [Framer](https://www.framer.com/) Framer 是一款低程式碼、基於人工智慧的拖放式網站建立器。 ![Framer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m0nb98taxppb2lq2j5ud.png) #### 14. [泡泡](https://bubble.io/) Bubble 自稱是世界上唯一的全端、無程式碼平台。 Bubble 是一款讓您無需編寫任何程式碼即可建立應用程式的工具。 ![氣泡](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tx9t207djk1rk3acimor.png) #### 15. [阿達洛](https://www.adalo.com/) Adalo 是一種低程式碼響應式 Web 應用程式設計工具。 ![Adalo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p9eyoci23wjrwfkbayhd.png) --- ## 其他 #### 16. [CDN JS](https://cdnjs.com/) CDN JS 是一個免費開源的內容傳遞網路。它允許 Web 開發人員直接搜尋 npm 套件並將其載入到靜態頁面的 HTML 頭部,而無需擔心 npm 安裝。 ![CDN JS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/33zhw7i6suw2fvd5uxfr.png) ## 免費圖片 #### 17. [Unsplash](https://unsplash.com/) 雖然我們有圖像生成工具,但沒有什麼比Unsplash帶給我們的超現實主義更重要了。您可以在網站上使用許多圖像(請記住向攝影師捐贈並在使用他們的圖像時提及他們)。 ![Unsplash](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/slj7w9m4t3g1d8ovcgvp.png) #### 18. [DALLE-3](https://openai.com/dall-e-3) Open AI 影像生成工具的第三次迭代。您可以使用 Bing AI 圖像產生器工具免費使用此工具。 ![DALLE-3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/agayg9j66sxts85t9or5.png) --- ## 模型 #### 19. [模型世界](https://www.mockupworld.co/) 大量免費、合法、完全分層、易於自訂的逼真 PSD 模型:可在您的專案、應用程式展示和演示中使用! 〜在他們的網站上提到! ![模型世界](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4uujz7r6rqwpeiimzy2o.png) #### 20.【免費模型世界】(https://www.freemockupworld.com/) Free Mockup World 是高品質、最佳免費模型的合作,包括 Apple 裝置、品牌、標誌、印刷、數位藝術、時尚、服裝等。 〜在他們的網站上提到。 ![免費模型世界](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dwa2ss6ueyra2w553yka.png) #### 21.【UI設計日報】(https://uidesigndaily.com/) 適合您網站的免費開源 UI 設計資源。 (包含登入頁面等的 Figma 模型) ![UI 設計日報](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yj9rxpndn5n82jv2tgij.png) --- ## 其他有用的開源程式庫 #### 22.【ShadCN】(https://ui.shadcn.com/) 使用 Radix UI 和 Tailwind CSS 建立的設計精美的元件。 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/epbhf6clfcprk88hiem0.png) #### 23. [點選投票](https://clickvote.dev/) Clickvote 是一個開源函式庫,可以省去圍繞內容建立反應元件的麻煩。 ![點擊投票](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q811a8q07g72taiib87e.png) #### 24. [斯巴達NG](https://www.spartan.ng/) ShadCN 用於 Angular。開源、社群建構。 ![斯巴達 UI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/odg6ubryxangvs7skvzp.png) --- ## 用於搜尋資料 - Swirl ### [漩渦](https://github.com/swirlai/swirl-search) **Swirl 是一個開源搜尋平台,它改變了您與資料互動的方式。** [![Swirl v3 演示](https://i.ibb.co/ZBY1HXD/Swirl-v3-Demo-1-2.gif)](https://github.com/swirlai/swirl-search) 將其視為專門為您的獨特資料集量身定制的 ChatGPT。無論是筆記、程式碼片段、PDF 檔案還是電子郵件,Swirl 都是您獲取即時、人工智慧驅動見解的首選平台。 Swirl 與眾不同的特質: - **一般搜尋**:無縫搜尋筆記、程式碼、文件、資料庫、電子郵件、聊天、日誌等。 🔍 - **個人人工智慧驅動的知識助理**:您可以為您的公司、新創公司或個人資料建立安全、可搜尋的知識庫。 🤖 - **一鍵檢索增強生成**:使用 Swirl,您可以立即執行人工智慧摘要和分析。您可以透過產生這些資料的資料來源來獲得答案。 🛠️ **請在 GitHub 上給 Swirl Search 一個 ⭐️。 💖** https://github.com/swirlai/swirl-search 在 GitHub 上給 Swirl ⭐ 並加入我們的【開源 Slack 社群 💕】(https://join.slack.com/t/swirlmetasearch/shared_invite/zt-1qk7q02eo-kpqFAbiZJGOdqgYVvR1sfw) --- 再次感謝您的閱讀!

自己用 20 行 JavaScript 來寫螢幕錄影功能!

假設您厭倦了螢幕錄影機的付費專區和限制,並想繼續編寫自己的程式碼 - 事實證明您已經可以透過幾行程式碼獲得基本功能。 原文出處:https://dev.to/ninofiliu/simple-screen-recorder-in-20-lines-of-javascript-4ina 我們可以要求瀏覽器使用[螢幕擷取API](https://developer.mozilla.org/en-US/docs/Web/API/Screen_Capture_API/Using_Screen_Capture)為我們取得擷取視訊串流,但出於安全原因我們必須確保[使用者手勢](https://stackoverflow.com/q/56388258/8186898)觸發捕獲,例如點擊按鈕: ``` const button = document.createElement("button"); button.innerHTML = "capture"; document.body.append(button); button.addEventListener("click", async () => { // TODO }); ``` 點擊後,獲取視訊串流並進行錄製 ``` const stream = await navigator.mediaDevices.getDisplayMedia(); const recoder = new MediaRecorder(stream); recoder.start(); ``` 當使用者停止分享螢幕時停止錄製 ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3k0wtf5udsvefz3hl88e.png) ``` const [video] = stream.getVideoTracks(); video.addEventListener("ended", () => { recoder.stop(); }); ``` 取得錄音檔案並下載 ``` recoder.addEventListener("dataavailable", (evt) => { const a = document.createElement("a"); a.href = URL.createObjectURL(evt.data); a.download = "capture.webm"; a.click(); }); ``` 瞧,你就有了一個簡單的螢幕錄影機! 它有很多解決起來很有趣的限制- 音頻錄製、網絡攝像頭集成、長時間執行的流等- 但我剛剛發現用這麼少的程式碼行就可以完成如此強大的事情,這太棒了,無法不分享。 [codepen連結](https://codepen.io/ninofiliu/embed/BaMzxQM)

經營個人頻道,改變了我的軟體工程師生涯

大家好,我想鼓勵一些想要開始當工程師,但很難找到第一份工作的人。還有那些因為懷疑自己的能力而難以開始/完成專案的人(冒牌者症候群)。我將告訴你我自己的旅程,以及我一路上學到的東西來,希望你能有動力繼續你的旅程。 原文出處:https://dev.to/chaoocharles/how-creating-content-as-a-developer-changed-my-life-270e 我叫查爾斯,來自非洲肯亞。我早在 2016 年就開始了我的編碼之旅,當時我進入大學,在 BTECH I.T 尋求職業生涯。在此之前,我對電腦了解不多,我只知道它們很酷,我想研究它們。在高中時,我是一名表現最好的學生,我的英語老師(也是副手,哈哈)認為我想做一些像計算機這樣簡單的事情而不是像工程、醫學、飛行員等更專業、更有前途的職業,這是愚蠢的,你說出它們的名字。好訊息是我沒有聽,而是去做了我想要的事情,而且我不會為此感到後悔。事實是,IT 領域的任何職業都是當今世界上最好的職業之一,世界頂級公司之所以能處於領先地位,是因為程式碼。看看 Netflix、亞馬遜、微軟、Facebook、Airbnb 或 Uber。所有這些公司都透過程式碼賺了數十億美元,因此不要讓任何人欺騙您,讓您認為您走在錯誤的道路上。我來這裡是為了告訴你,你正走在最好的道路上。 回想2016年剛入職第一年的時候,由於出身卑微,擁有一台筆記型電腦對我來說是非常困難的,即使是一台簡單的筆記型電腦,甚至是二手的筆記型電腦。如果我要做 I.T,那麼擁有一個對我來說也是強制性的。擁有一部像樣的智慧型手機也是一個問題,但幸運的是,我有一個三星口袋(那些小三星手機,如果你還記得的話),並在說服朋友用它與我交換一些錢和一部按鍵手機後。這款手機在這個故事中很重要,因為它是我用來開始學習程式設計的手機。在學校裡,我們被教導如何編碼,是的,但這還不夠,它主要是理論。關於編碼的事情是你必須_練習_、_練習_、再_練習_。於是,我從同學那裡了解到了一個名為sololearn的應用程式。我在那裡開始學習 Web 開發,包括 html、css、javascript、php、sql,我想還有一點 jquery。這個應用程式教會了我有關這些主題的所有基礎知識,並且在完成每節課後它都有有趣的挑戰和徽章。唯一的問題是我不會透過手機進行完整的專案編碼。但重點是,當您等待購買筆記型電腦時,您絕對可以開始透過智慧型手機學習程式設計。因此,不要因為沒有筆記型電腦而高枕無憂。你越早意識到沒有人來拯救你越好。 我繼續從我的三星口袋裡學習了一個月,後來在內羅畢街頭(有很多扒手)它被神秘地偷走了。學校的朋友送了我一部HTC手機,螢幕碎了,有些地方根本碰不著,我得旋轉螢幕多次才能碰到地方😂,不過乞丐不挑食,我就繼續用了以便在本學期剩下的時間裡學習更多有關編碼的知識。 第二學期,現在是2017年,我收到了學生貸款。我的一些朋友/同學用他們的貸款去聚會、喝酒以及在俱樂部與女孩們玩耍。嗯,就我而言,我知道自己從哪裡來,也知道自己要去哪裡。於是,我拿了一些錢,立刻買了一台筆記型電腦。剩下的錢用來付學費和一點生活費。這對我的案例來說是一個巨大的進步,因為我現在可以了解更多資訊並開始從筆記型電腦上處理專案。因此,如果您有錢,請停止考慮參加聚會和購買昂貴的東西,而是考慮如何用這筆錢讓您的生活變得更好。 2017年至2019年期間,沒有太大變化。我只是在學習和做學校作業等。我想我還用 HTML 和 CSS 製作了兩個網站,我為這些工作獲得了一些報酬。我探索了更多關於編碼的知識,包括學習Java 中的OOP(物件導向程式設計),也用Java 進行了一些Android 應用程式開發,我的筆記型電腦無法處理android studio 😂,所以我又回到了Web 開發。我探索了 WordPress 以及如何用它製作博客等,並建立了一個 WordPress 博客,並以幾美分的價格出售。 2019年底,我正在讀三年級第三學期(這在我們大學被稱為內部工業實習),大約在這個時候,我被敲響了警鐘。我意識到我一直在學習編碼,但除了簡單的 html、css 和 WordPress 網站之外,我仍然無法建立一個完整的專案。我對任何一種程式語言都沒有足夠的信心。另外,畢業的要求是在第四年完成一個編碼專案。我也開始對未知產生恐懼,例如放學後要做的事情,因為只剩下一年了。我開始做很多研究如何建立一個完整的網絡應用程式,因為我已經了解了 javascript 的基礎知識,並且出現了一件我不知道的事情,即 javascript 框架,目前最流行的是 Angular、Vue並做出反應。當時我就知道我必須學習這些框架之一,而且很難決定選擇哪一個,但我最終選擇了 React,因為它是所有框架中最受歡迎、最有前途的工作,而且我仍然使用 React 進行編碼這點。 我嘗試從sololearn學習React,但進展並不順利。我嘗試了 youtube 並發現了 @thenetninja 頻道:https://www.youtube.com/@NetNinja 它非常有益健康,這就是我對 React 的很好的介紹。後來我從 Udemy 學習了兩門完整的 React 課程,一門由 _Stephen Grider_ 教授,另一門由 _Maximilian Schwarzmüller_ 教授。順便問一下,我沒有完成它們,誰完成了 udemy 課程? 😂 但這兩門課程教會了我更多關於 React 的高級知識。 在學習 React 的過程中,我也很好奇如何在放學後或還在學校的時候透過程式碼賺錢,我發現了幾個選擇,找工作、自由工作、建立內容(這可以是寫部落格或 YouTube 頻道) )、開始播客、寫書、建立像udemy 這樣的課程等等。由於我還在上學,我知道找工作很難處理,所以我決定嘗試自由工作和內容創作。還是在 2019 年,我開設了 YouTube 頻道:https://www.youtube.com/c/chaoocharles 來教授編碼,也開設了一個 upwork 帳號來從事自由專案的編碼。 我知道我不是一個好的作家,正如你從這篇文章中絕對可以看出的那樣,所以我嘗試了影片而不是博客。這是另一個挑戰,因為我必須學習如何製作影片、學習錄製和編輯軟體等等。但我還是堅持了下來,並從同學那裡得到了我的前 100 個訂閱。我的影片一開始就很糟糕,而且我做了很多工作,甚至沒有得到一分錢。但從正面的角度來看,製作影片讓我更理解編碼概念。就像,對我來說,要解釋我必須先理解的東西。我主要用 html、css 和 React 建立了很多影片,做得越多,我對建立影片和編碼就越有信心。 2020 年,我有很多時間來做這一切,因為我們因新冠疫情關閉了學校近一年,經過一年的努力,我終於獲得了 1000 名替補,這對我來說是一個巨大的勝利。 2020 年中期,我取得了兩場重大勝利,在 YouTube 上達到了 1k,並且在 Upwork 上找到了我的第一個客戶。我需要 1000 訂閱者和 4000 小時的觀看時間,YouTube 才會開始向我付費。我距離 4k 觀看時間還很遠,但至少我已經達到了其中一項要求。 Upwork 也很難找到第一個客戶,我申請工作卻無濟於事,但這第一個客戶改變了遊戲規則。我讓他相信我知道如何編碼,並用我的 YouTube 教程證明了這一點。你看,在製作 YouTube 教學的同時,我也在為自己建立一個作品集,我也在我的 github 上發布了多個專案。這麼說吧,我的投資組合目前看起來非常好,這位客戶毫不猶豫地給了我一份合約。如果你碰巧教了一些東西,人們就會開始將你視為專家(即使你正在努力教那件事😂)這可以通過影片或博客,我認為你應該嘗試一下。我在 upwork 專案上做得很好,這個客戶在那一年和接下來的一年裡繼續給我更多的專案。我做了他的大約 8 個專案,在 upwork 上獲得了上升人才徽章,後來又獲得了頂級徽章,這讓我贏得了更多客戶。 ![Upwork](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jut1tydubsj4mwlmnt3h.png) 是的,我知道我現在的工作成功分數很差,但你明白了,哈哈😂 在製作YouTube 影片和Upwork 專案時,我也在做我的最後一年專案,因為我現在已經是第四年了,但這些是我自從2020 年因新冠疫情在家以來所做的唯一事情。雖然在2020 年底,我們回去上學期,做了考試並展示了專案。 快轉到 2021 年,我現在正在做附件。這是我畢業的必要條件。我透過在 Facebook 和網路上尋找肯亞的網路開發公司,輕鬆獲得了這一點。評論他們的帖子並解釋我的 IT 背景。我從某家新創公司的 CEO 那裡得到了 DM,並且以前端開發人員的身份加入了那裡。我試圖就報酬進行談判,但最好的結果只是維持交通和午餐,每週去辦公室三天,並承諾在實習後獲得一份長期工作。作為一名學生,這已經足夠好了,所以我就這麼做了。 在這家公司,我的 CSS 和 React 技能給他們留下了深刻的印象。我改造了他們公司的網站,並在我在那裡的5個月期間又做了2個網站。學校對我進行了評估,後來公司給了我工作機會。我覺得每個月的收入對我的技能來說不夠好,因為我可以在一兩週內輕鬆地做同樣的自由職業,而且我在那裡的時候我的 YouTube 也得到了貨幣化。我只是拒絕了這個提議,並決定專注於我的自由職業和內容創作之旅。如果他們允許我在處理其他事情的同時遠端處理他們的專案,也許我會接受這個提議,但這不在他們的公司政策中。我不想滿足於更少。你看,過去幾年我所做的一切都給了我選擇,也讓我不再急於找到工作,並擁有競爭優勢。 2021 年年中,我以二等高年級畢業,我保證如果不是我用 YouTube 和 upwork 分散自己的注意力,我會獲得一等,第四年我表現最差。但我後悔嗎?不。問題是,我從來沒有用過那個學位,它仍然鎖在家裡的某個地方,沾滿了灰塵。好處是,技能和經驗是這個編碼和程式設計領域最重要的。只有少數公司可能會要求學位,但大多數公司不會。他們會詢問您過去的經驗、您從事過的專案,並希望您通過程式設計面試。因此,如果你正在尋找一份程式設計工作,並因為沒有獲得學位而指責自己沒有學位,那麼你應該停下來。我們大多數擁有學位的人甚至沒有使用它們。也許我們唯一的優勢是我們在學校建立的聯繫或從那裡獲得的技能。但說實話,我所知道的大部分內容都是我自學的,我相信每個程式設計師都是自學的程式設計師,無論他們是否上過學。你必須親自動手。光靠論文並沒有太大幫助。 畢業後,我開始從 YouTube 獲得專案邀請,以及報酬豐厚的專案。我也開始利用 YouTube 和 GitHub 來在 Upwork 上獲得更好的付費專案,透過分享我的個人資料連結來告訴客戶我所取得的成就。所以,所有這些加起來就很不錯了。現在,我僅透過內容創作來支付所有帳單,並透過在工作和外部工作專案上工作來獲得更多收入。我的時間也很靈活,在家工作,這很棒。 2022 年我只做了一份全職工作。雖然位置偏遠,但完全值得。 我的觀點是,如果你正在努力尋找一份工作或一個專案,你可以透過為自己建立一些東西來改變一切。建立部落格、建立播客、建立頻道、建立公司、建立課程、寫書、公開建置(啟動一個大型專案並在此處和 Twitter 上分享您的進度),只需在這裡展示您的技能即可您能做什麼,遲早你會開始從事高薪專案。停止追逐工作,而只是吸引他們。 正如你從我的旅程中可以看出的,這不是一天的成就,直到一年多我才得到一分錢的內容創作報酬,直到一年多我才得到一個客戶的工作。我不是一天就能學會程式設計的,我是從一部手機開始的,後來又是用學校貸款買的一台低階筆記型電腦(我甚至還沒付)。所有這些成功的人士和公司都是從某個地方開始的,您今天就可以開始改變您的生活。開始親自動手,兩三年後你甚至不會相信自己來自哪裡。 這是我的故事,我希望你學到了一兩件事✌️

React 生態系 2024 年推薦總整理

2024 年,React 將慶祝其成立 11 週年,值得期待 React 生態系統中令人興奮的發展。在本部落格中,我們將基於 2023 年發生的情況以及來年的預期,探討生態系統的各個面向。 原文出處:https://dev.to/avinashvagh/react-ecosystem-in-2024-418k ## 1. 路由 路由一直是Web開發的關鍵部分,在2023年,我們看到了各種各樣的路由解決方案。讓我們看看2024年會發生什麼: - **React Router:** React Router 仍然是 React 應用程式中處理路由的基本選擇。憑藉其廣泛的文件和活躍的社區,它仍然是應用程式中聲明式路由的可靠選擇。 - **React Query:** Tanstack 的 React Query 在 2023 年流行的基礎上,旨在增強資料擷取和狀態管理。它簡化了 React 應用程式中管理、快取和同步資料的過程。 - **Next.js:** Next.js 是一個建立在 React 之上的框架,預計將保持其作為具有靈活路由選項的伺服器渲染 React 應用程式首選的地位。它的官方文件是 Next.js 應用程式中路由的寶貴資源。 2024 年,React 充滿活力的生態系統將繼續蓬勃發展,為開發人員提供豐富的工具和函式庫。請繼續關注 React 世界的更多更新和進步。 ## 2. 客戶端狀態管理 客戶端狀態管理是現代 Web 開發的一個重要方面,可以在前端應用程式中實現高效的資料處理。 Redux Toolkit 和 Zustand 是兩種流行的用戶端狀態管理解決方案。以下是兩者的簡要概述: ### 1. **Redux Toolkit** - **網址:** [Redux Toolkit](https://redux-toolkit.js.org/) Redux Toolkit 是一個建立在 Redux 之上的綜合狀態管理函式庫,Redux 是 React 應用程式中成熟的狀態管理函式庫。它提供了一組工具和最佳實踐,以可預測且高效的方式簡化狀態管理流程。 Redux Toolkit 的結構化方法(包括 actions、reducer 和 store)非常適合複雜的大型專案。它提倡採用集中式和聲明式的狀態管理方法。 ### 2. ** Zustand** - **示範:** [Zustand Demo](https://state-demo.pmnd.rs/) Zustand 是一個輕量級且靈活的狀態管理庫,專為小型專案或喜歡更簡單解決方案的開發人員而設計。它簡化了狀態管理,無需複雜的設定和概念。 Zustand 以其簡單性和易用性而聞名,這使其成為小型應用程式和重視更輕量級方法的人的絕佳選擇。 在 Redux Toolkit 和 Zustand 之間進行選擇時,請考慮專案的複雜性以及您對 Redux 的熟悉程度。 Redux Toolkit 是大型、結構化應用程式的絕佳選擇,而 Zustand 則非常適合需要快速、簡單的狀態管理解決方案的小型專案。 ## 3.伺服器狀態管理 伺服器狀態管理是 Web 開發的一個重要方面,特別是對於跨客戶端和伺服器的應用程式。以下是兩個可以幫助您有效管理伺服器狀態的關鍵庫: ### 1. **TanStack Query** - **文件:** [TanStack Query](https://tanstack.com/query/latest) TanStack Query 是一個強大且靈活的狀態管理庫,用於處理應用程式中的伺服器狀態。它允許您輕鬆地從伺服器獲取、快取和更新資料。該程式庫提供自動快取、高效資料擷取以及自訂 API 端點的功能等功能。對於需要即時資料更新和高效資料同步的應用程式來說,它是管理伺服器狀態的絕佳選擇。 ### 2. **Redux 工具包 - RTK Query** - **文件:** [Redux 工具包 - RTK 查詢](https://redux-toolkit.js.org/rtk-query/overview) RTK Query 是 Redux Toolkit 生態系統的一部分,提供管理伺服器狀態的全面解決方案。它以可預測且高效的方式簡化了發出 API 請求、快取資料和更新狀態的過程。 RTK Query 與 Redux 無縫集成,對於使用 Redux 進行狀態管理的應用程式來說是一個絕佳的選擇。它提倡最佳實踐並提供結構化方法來處理伺服器狀態。 選擇伺服器狀態管理庫時,請考慮您的專案需求、資料擷取需求的複雜性以及您對 Redux 的熟悉程度(如果您選擇 RTK 查詢)。這兩個庫都提供了用於管理應用程式中的伺服器狀態的強大解決方案。 ## 4. 表單處理 表單處理是建立 Web 應用程式的關鍵部分,尤其是在 React 中。用於表單處理的兩個流行的程式庫是 Formik 和 React Hook Form。概述如下: ### 1. ** Formik** - **網址:** [Formik](https://formik.org/) Formik 是在 React 中建立表單最常用的函式庫。它提供了一組實用程式和元件,可以輕鬆管理表單狀態、驗證和提交。雖然它是一個流行的選擇,但截至最新訊息,Formik 並未得到積極維護,這可能會影響其與未來 React 更新和不斷發展的最佳實踐的兼容性。使用 Formik 的唯一缺點是它不被維護。 Formik 文件/網站甚至不鼓勵在新專案中使用 Formik。 ### 2. **React Hook Form** - **網址:** [React Hook 表單](https://www.react-hook-form.com/) React Hook Form 是一個現代表單函式庫,它利用 React hooks 來有效地處理表單狀態和驗證。它得到積極維護,並提供輕量級且直觀的 API。 React Hook Form 以其效能和靈活性而聞名,使其成為在 React 應用程式中處理表單的絕佳選擇。 在 Formik 和 React Hook Form 之間進行選擇時,請考慮維護和專案的特定要求等因素。根據最新訊息,React Hook Form 因其積極的開發和現代的表單處理方法而成為推薦選擇。 ## 5. 測試 測試是軟體開發過程的關鍵部分,有各種工具和程式庫可協助開發人員編寫有效的測試。以下是一些用於測試的資源和工具: ### 1. **ViTest** - **網址:** [ViTest](https://vitest.dev/) ViTest 是一個由 vite 支援的單元測試框架。它提供了一種為 React、Vue、Svelte 等應用程式編寫單元測試、元件測試和端到端測試的簡單方法。如果您使用 React,ViTest 可以透過全面的測試來幫助您確保程式碼的可靠性和品質。 ### 2. **React 測試函式庫** - **文件:** [React 測試庫](https://testing-library.com/docs/react-testing-library/intro/) React 測試庫是 React 應用程式的熱門測試庫。它專注於編寫模擬使用者互動的測試,幫助您確保元件從使用者的角度按照預期執行。該程式庫鼓勵測試 React 元件的最佳實踐。 ### 3. ** Playwright** - **網址:** [Playwright](https://playwright.dev/) Playwright 是一個端對端測試框架,支援多種瀏覽器,包括 Chromium、Firefox 和 WebKit。它為瀏覽器自動化提供了統一的 API,並允許您編寫測試來驗證 Web 應用程式在不同瀏覽器上的功能。 Playwright 是確保跨瀏覽器相容性的強大工具。 這些資源和工具可以幫助您涵蓋測試的各個方面,從單元測試到端到端測試,具體取決於您的專案需求和您正在使用的技術。請務必進一步探索它們,以選擇最適合您要求的一種。 ## 6. 樣式 當談到 Web 開發中的樣式時,有幾種流行的工具和庫可供選擇。以下是三個值得注意的選項: ### 1. **Tailwind CSS** - **網址:** [Tailwind CSS](https://tailwindcss.com/) Tailwind CSS 是一個實用程式優先的 CSS 框架,它提供了一組預先建立的原子 CSS 類別來設計您的 Web 應用程式。它旨在透過在 HTML 中編寫實用程式類別來幫助您快速建立響應式且高度可自訂的設計。 Tailwind CSS 以其靈活性而聞名,對於想要實用程式驅動的樣式設計方法的開發人員來說是一個絕佳的選擇。 ### 2. **樣式元件** - **網址:** [樣式元件](https://styled-components.com/) Styled Components 是一個 CSS-in-JS 函式庫,用於設計 React 元件的樣式。它允許您透過使用標記模板文字定義樣式元件來直接在 JavaScript 檔案中編寫 CSS。這種方法使您能夠將樣式封裝在元件中,從而更輕鬆地管理和維護 CSS。樣式化元件在 React 生態系統中特別受歡迎。 ### 3. ** Emotion** - **文件:** [Emotion](https://emotion.sh/docs/introduction) Emotion 是另一個 CSS-in-JS 函式庫,重點是效能和靈活性。它提供了多種方法來定義樣式並將其應用到 React 元件,包括字串和物件樣式。 Emotion 以其可預測性和適合使用 JavaScript 編寫不同 CSS 樣式而聞名。它提供了一種與框架無關的方法,使其適用於各種 JavaScript 框架。 這些工具中的每一個都有自己的優勢,並且適合不同的用例。 Tailwind CSS 擅長使用實用程式類別進行快速 UI 開發。 Styled Components 和 Emotion 是 React 應用程式中元件級樣式的理想選擇。您的選擇將取決於您的專案要求和個人喜好。 ## 7.UI元件庫 用於在 2023 年建立使用者介面的 UI 元件庫,並將在 2024 年繼續使用。 ### 1. ** Material-UI** - **網址:** [Material-UI](https://mui.com/) Material-UI 是一個受歡迎且維護良好的 React UI 框架。它基於 Google 的 Material Design 指南,並提供廣泛的元件來建立現代且具有視覺吸引力的使用者介面。 ### 2. ** Mantine** - **網址:** [Mantine](https://mantine.dev/) Mantine 是一個現代 React 元件庫,專注於提供高品質的元件和鉤子。它提供了各種 UI 元素和工具來簡化您的開發流程。 ### 3. ** Ant Design** - **網址:** [Ant Design](https://ant.design/) Ant Design 是一個用於建立企業級 React 應用程式的綜合設計系統和元件庫。它以其豐富的元件和強調自然清晰的設計理念而聞名。 ### 4. ** Chakra UI** - **網址:** [Chakra UI](https://chakra-ui.com/) Chakra UI 是在 React 中建立可存取且高度可自訂的使用者介面的熱門選擇。它提供了一組可組合元件和一個樣式道具系統,用於靈活的樣式設定。 ### 5. ** Headless UI(Tailwind CSS 框架)** - **網址:** [Headless UI](https://headlessui.com/) Headless UI 是一組完全可存取、無樣式的 UI 元件,旨在與 Tailwind CSS 無縫協作。它允許您建立可存取的介面,同時保留對樣式的完全控制。 ### 6. **DaisyUI(Tailwind CSS 框架)** - **網址:** [DaisyUI](https://daisyui.com/) DaisyUI 是 Tailwind CSS 的擴展,它帶來了額外的元件和實用程式來增強您的開發體驗。如果您已經在使用 Tailwind CSS,它會特別有用。 ### 7.**Shadcn UI(Tailwind CSS 框架)** - **網址:** [Shadcn UI](https://ui.shadcn.com/) Shadcn UI 是另一個基於 Tailwind CSS 的 UI 元件庫,它提供了一系列元件和實用程序,用於快速有效地建立 Web 應用程式。 這些程式庫提供了各種元件和工具,可協助您在 React 應用程式中建立響應靈敏且具有視覺吸引力的使用者介面。庫的選擇取決於您的專案的要求和您的個人喜好。 ## 8. 動畫 如果您對 React 動畫庫感興趣,兩個流行的選擇是: 1. **React Spring** - 您可以在 React Spring 的官方網站 [react-spring.dev](https://www.react-spring.dev/) 上找到有關 React Spring 的更多資訊和文件。 React Spring 是一個功能豐富的動畫庫,它利用基於實體的動畫在 React 中建立流暢的互動式動畫。 2. **Framer Motion** - 另一個出色的選擇是 Framer Motion,您可以在 [framer.com/motion](https://www.framer.com/motion/) 進一步探索它。 Framer Motion 因是專為 React 設計的功能豐富的動畫庫而聞名。它提供了靈活性,非常適合在 React 應用程式中建立流暢的動畫。 這兩個庫都有其優點,它們之間的選擇可能取決於您的特定專案要求和個人喜好。 React Spring 提供基於實體的動畫和豐富的功能集,而 Framer Motion 以其易用性和靈活性而聞名。最好對兩者進行探索,看看哪一個更符合您的動畫需求。 請隨意參考各自的網站以獲取詳細的文件和範例,以便做出明智的選擇。 ## 9. 資料視覺化 當涉及 React 中的資料視覺化時,有幾個函式庫可以幫助您建立互動式且資訊豐富的圖表和圖形。以下是三個流行的選項: 1. **Victory** - 您可以在 [formidable.com/open-source/victory/docs](https://formidable.com/open-source/victory/docs) 中瀏覽 Victory 的文件 Victory 是一個強大的 React 資料視覺化函式庫,提供廣泛的圖表類型和自訂選項。它旨在輕鬆建立具有視覺吸引力的互動式資料視覺化。 2. **React Chartjs 2** - 造訪 [react-chartjs-2.js.org](https://react-chartjs-2.js.org/) 以了解更多資訊。 React Chartjs 2 是 Chart.js(一個流行的 JavaScript 圖表庫)的 React 包裝器。它提供了一種將 Chart.js 整合到 React 應用程式中的簡單方法,可讓您使用 Chart.js 的底層功能建立各種圖表和圖形。 3. **Recharts** - 有關Recharts的詳細訊息,您可以參考[recharts.org/en-US/](https://recharts.org/en-US/)。 Recharts 是一個使用 React 建立的可組合圖表庫。它提供了一個簡單而靈活的 API 來建立各種類型的圖表,非常適合將資料視覺化加入到您的 React 專案中。 每個庫都有自己的一組功能和優點,因此選擇將取決於您的特定專案要求和個人喜好。您可以存取他們各自的文件以了解更多資訊並開始使用 React 中的資料視覺化。 ## 10. 表 如果您正在尋找有關 React 中表格的訊息,可以在 [tanstack.com/table/v8](https://tanstack.com/table/v8) 上瀏覽版本 8 的 TanStack Table 文件。 TanStack Table 是一個無頭 UI 庫,可讓您在 TS/JS、React、Vue、Solid 和 Svelte 等各種框架中建立強大的表格和資料網格,同時保留對標記和樣式的控制。該文件將為您提供有關如何使用 TanStack Table 和配置表的詳細訊息,包括選項和 API 屬性。 無論您使用 TypeScript 還是 JavaScript 以及使用受支援的框架之一,TanStack Table v8 都提供了一種靈活的解決方案,用於在 Web 應用程式中建立表格和資料網格。該文件將引導您完成整個過程,並幫助您充分利用該庫來滿足您的特定需求。 ## 11. 國際化(i18n) 當涉及 React 應用程式中的國際化 (i18n) 時,有多個程式庫和工具可協助您管理翻譯和在地化。 React 中 i18n 的兩個突出選項是: 1. **i18next** - 您可以在 [react.i18next.com](https://react.i18next.com/) 找到使用 i18next 的文件和資源。 i18next 是一個流行的 JavaScript 國際化框架,包括 React。它提供了處理翻譯、格式化等的全面解決方案。 2. **React-Intl (Format.js)** - React-Intl 的文件是 Format.js 專案的一部分,可以在 [formatjs.io/docs/react-intl](https://formatjs.io/docs/react-intl)。 React-Intl 是一個函式庫,提供用於在 React 應用程式中格式化和處理國際化文字的工具。 這兩個函式庫都有活躍的社群、豐富的文件,並且在 React 生態系統中廣泛使用。您可以探索這些資源,以確定哪一個最適合您的 React 應用程式國際化需求。 ## 12. 開發工具 DevTools 對於偵錯和改進 Web 應用程式的開發工作流程至關重要。以下是一些流行的 React 開發工具和相關函式庫: 1. **React 開發者工具** - 該工具可作為 Chrome 擴充功能使用。它允許您檢查 React 元件層次結構、查看元件的狀態和 props,甚至更改元件的狀態以進行測試。您可以從 [Chrome Web Store](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi) 安裝它。 2. **Redux DevTools** - Redux DevTools 是另一個 Chrome 擴展,可以增強 Redux 開發工作流程。它提供了對 Redux 儲存的深入了解,讓您可以檢查操作和狀態變更、倒回和重播操作等。您可以從 [Chrome Web Store](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd) 安裝它。 3. **Testing Playground** - Test Playground 是一個 Chrome 擴展,可以簡化 React 元件的測試。它提供了一個用於試驗元件及其道具的視覺環境。您可以在 [Chrome 線上應用程式商店](https://chrome.google.com/webstore/detail/testing-playground/hejbmebodbijjdhflfknehhcgaklhano) 上找到它。 4. **React Hook Form DevTools** - 對於使用 React Hook Form 的用戶,可以使用 DevTools 來協助偵錯表單行為。您可以在 [React Hook Form 網站](https://www.react-hook-form.com/dev-tools/) 上存取它們。 5. **TanStack Query DevTools** - TanStack Query 是 React 的資料擷取庫,它提供用於偵錯和檢查查詢和突變的 DevTools。您可以參考[官方文件](https://tanstack.com/query/v4/docs/react/devtools)以了解更多資訊。 這些開發工具可協助開發人員簡化開發和偵錯流程,從而更輕鬆地建置和維護 Web 應用程式。 ## 13. 文件 文件對於任何軟體專案都至關重要。以下是用於建立文件的兩種流行工具: 1. **Docusaurus** - Docusaurus 是一種廣泛採用的用於建立文件網站的工具。它是一個開源框架,為建立和維護文件提供了乾淨且用戶友好的介面。 Docusaurus 具有高度可自訂性,許多專案和組織都使用它來建立文件網站。您可以在 Docusaurus 的[官方網站](https://docusaurus.io/)上了解更多並開始使用 Docusaurus。 2. **Nextra** - Nextra 是建立文件網站的另一種選擇。雖然 Nextra 可能不像 Docusaurus 那樣出名,但它提供了一種現代且簡約的方法來建立文件。它的設計是輕量級且用戶友好的,對於那些喜歡簡單乾淨的文件風格的人來說是一個不錯的選擇。您可以在 Nextra 的[官方網站](https://nextra.site/) 上探索有關 Nextra 的更多資訊。 Docusaurus 和 Nextra 都有各自的優勢,它們之間的選擇取決於您的特定需求和偏好。您可以存取他們各自的網站以了解更多資訊、存取文件並確定哪一個最適合您的專案。 ## 14. 元件開發環境 元件開發環境 (Dev Env) 對於有效建置和測試 UI 元件至關重要。用於為 UI 元件建立開發環境的廣泛使用的工具之一是 [Storybook](https://storybook.js.org/)。 Storybook 是業界標準的元件瀏覽器,可讓開發人員獨立開發 UI 元件。當處理設計系統或元件庫時,它特別有價值。以下是 Storybook 如何協助建立 UI 元件的開發環境: 1. **目錄 UI 元件**:Storybook 提供了用於編目和顯示 UI 元件的專用環境。開發人員可以單獨查看每個元件的外觀和行為。 2. **將元件變體儲存為故事**:在 Storybook 中,開發人員可以為每個元件建立「故事」。這些故事代表元件的不同變體或用例。這是記錄和展示元件行為的絕佳方式。 3. **開發人員體驗工具**:Storybook 提供了一系列開發人員體驗工具,包括熱模組重新加載,以簡化元件開發流程。 透過使用 Storybook,您可以有效率地開發、測試和記錄 UI 元件。它在設計系統時特別有用,因為它允許您專注於單個元件及其互動。您可以在 Storybook 的[官方網站](https://storybook.js.org/) 上了解更多並開始使用。 它是一種多功能工具,可以根據專案的特定需求進行定制,使其成為元件開發環境的寶貴資產。 ## 15. 類型檢查 TypeScript 是 Microsoft 開發的一種程式語言,透過新增靜態類型來擴充 JavaScript。它提供全面的類型檢查和強大的類型系統,以捕獲開發過程中的錯誤並提高程式碼品質。以下是 TypeScript 中類型檢查的一些關鍵方面: 1. **靜態型別系統**:TypeScript 引進了靜態型別系統,這表示在編譯時檢查類型。這有助於在執行程式碼之前辨識與類型相關的錯誤。 2. **型別註解**:開發者可以使用型別註解來指定變數、函數參數和傳回值的型別。這提供了清晰度並確保變數的使用一致。 3. **推斷**:TypeScript 可以根據指派給變數的值推斷類型。這減少了對顯式類型註解的需求並提高了程式碼簡潔性。 4. **類型聲明**:TypeScript支援自訂類型的聲明,例如介面和枚舉,以定義資料結構的形狀並增強程式碼的可維護性。 5. **類型相容性**:TypeScript 有一個檢查類型相容性的系統,這確保你不能將不相容的類型指派給變數。這有助於防止常見的執行時錯誤。 6. **對 JavaScript 文件進行類型檢查**:TypeScript 還可以檢查 JavaScript 文件,讓您可以逐步將 TypeScript 引入現有的 JavaScript 專案中。 透過將 TypeScript 合併到您的開發工作流程中,您可以從這些類型檢查功能中受益,從而儘早發現錯誤、增強程式碼可維護性並提高程式碼的整體品質。您可以在[官方 TypeScript 網站](https://www.typescriptlang.org/) 上了解有關 TypeScript 及其類型檢查功能的更多資訊。 ## 16. 行動應用程式 如果您想要開發行動應用程式,特別是 Android 和 iOS 的行動應用程式,React Native 是一個值得考慮的有價值的框架。 React Native 是一個開源框架,可讓您使用 JavaScript 和 React 建立行動應用程式。這就是 React Native 成為行動應用程式開發的熱門選擇的原因: 1. **跨平台開發**:React Native 使您能夠使用單一程式碼庫開發適用於 Android 和 iOS 的應用程式。這種方法可以顯著減少開發時間和工作量。 2. **可重複使用元件**:您可以建立跨平台工作的可重複使用 UI 元件,幫助您在應用程式中保持一致的外觀和感覺。 3. **熱重載**:React Native 支援熱重載,這意味著您可以立即看到程式碼變更的結果,而無需重新編譯整個應用程式。這加快了開發速度。 4. **大型社區**:React Native 擁有龐大且活躍的社區,這意味著您可以找到豐富的資源、庫以及常見問題的解決方案。 5. **本機效能**:React Native 應用程式具有接近本機的效能,因為它們使用本機元件進行渲染。這確保了流暢的用戶體驗。 6. **成本效益**:透過在 Android 和 iOS 之間共用程式碼庫,您可以降低開發成本。 要開始使用 React Native,您可以造訪官方網站 [React Native](https://reactnative.dev/) 以取得全面的文件、教學和資源。無論您是初學者還是經驗豐富的開發人員,React Native 都是行動應用程式開發的強大選擇。 ## 17. 為 React 開發人員提供的很棒的函式庫 很高興看到您對 React 開發人員的優秀庫感興趣。以下是一些非常有用的程式庫,可用於 React 開發中的各種功能: ### 1. **用於拖放功能的 DND 套件** - 網址:[DND Kit](https://dndkit.com/) DND Kit 是一個強大的庫,用於為 React 應用程式加入拖放功能。它提供了一種簡單且可自訂的方法來實現拖放功能,以便在使用者介面中重新排序、重新排列或組織元素。 ### 2. **React Dropzone 用於檔案上傳** - 網址:[React Dropzone](https://react-dropzone.js.org/) React Dropzone 是一個流行的程式庫,用於在 React 應用程式中處理檔案上傳。它提供了一個用戶友好且高度可自訂的 dropzone 元件,簡化了上傳文件的過程,使其成為任何需要文件上傳的專案的有價值的補充。 ### 3. **Firebase 用於身份驗證** - 網址:[Firebase](https://firebase.google.com/) Firebase 由 Google 開發,是一個用於建立 Web 和行動應用程式的綜合平台。它提供廣泛的服務,包括用戶身份驗證。透過 Firebase 驗證,您可以輕鬆地將安全的使用者註冊和登入功能新增到您的 React 應用程式中。 ### 4. **Supabase 用於身份驗證** - 網址:[Supabase](https://supabase.com/) Supabase 是 Firebase 的開源替代品,提供一套用於建立應用程式的服務,包括身份驗證。它提供了可以無縫整合到您的 React 專案中的用戶身份驗證功能。 這些程式庫涵蓋了 React 開發的基本面,包括拖放功能、檔案上傳和使用者身份驗證。根據您的專案要求,您可以利用這些程式庫來增強您的 React 應用程式。 **免責聲明:**“本文是在人工智慧的幫助下建立的”

8款新潮好用的 React 套件分享

原文出處:https://dev.to/github20k/8-components-to-become-a-react-master-2ee4 # 簡介 我收集了可用於建立終極網站的 React 元件。 他們每個人都有獨特的用例! 別忘了給他們加星號🌟 那麼就讓我們開始吧! ![讓我們開始吧](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gxaa9vnqc8ye5a0g1iv2.gif) --- ## 1. [Clickvote](https://github.com/clickvote/clickvote?utm_source=dev&utm_medium=react-component-expert) - 按讚、投票並查看任何上下文。 👑 [![Clickvote](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2yn237newdjgm4uhl1p1.png)](https://github.com/clickvote/clickvote?utm_source=dev&utm_medium=react-clickvote/clickvote?utm_source=dev&utm_medium=react-元件專家) 將點讚和評論元件無縫整合到您的應用程式中。 使用這個簡單的 React 程式碼渲染喜歡框、評論框和反應元件! ``` import { ClickVoteProvider } from '@clickvote/react'; import { ClickVoteComponent } from '@clickvote/react'; import { LikeStyle } from '@clickvote/react'; <ClickVoteProvider> <ClickVoteComponent id={CONTEXT} voteTo={ID}> {(props) => <LikeStyle {...props} />} </ClickVoteComponent> </ClickVoteProvider> ``` 在這裡加星號🌟 [https://github.com/clickvote/clickvote](https://github.com/clickvote/clickvote?utm_source=dev&utm_medium=react-component-expert) --- ## 2. [Novu](https://github.com/novuhq/novu) - 將應用程式內通知新增至您的應用程式! [![Novu](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wyb47s6sbh232x77f794.png)](https://github.com/novuhq/novu) 用於在一個地方管理所有通訊管道的簡單元件和 API:電子郵件、SMS、Direct 和 Push 您可以使用此 React 元件為您的應用程式新增應用程式內通知 ``` import { NovuProvider, PopoverNotificationCenter, NotificationBell, IMessage, } from "@novu/notification-center"; <NovuProvider subscriberId={"SUBSCRIBER_ID"} applicationIdentifier={"APPLICATION_IDENTIFIER"} > <PopoverNotificationCenter colorScheme="dark"> {({ unseenCount }) => <NotificationBell unseenCount={unseenCount} />} </PopoverNotificationCenter> </NovuProvider> ``` 在這裡加星號🌟 https://github.com/novuhq/novu     ## 3. [CopilotKit](https://github.com/RecursivelyAI/CopilotKit) - 使用 GPT 將自動補全功能加入您的文字! [![CopilotKit](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3bvi730jwuggjti7peg8.png)](https://github.com/RecursivelyAI/CopilotKit) 適用於任何 React 應用程式的強大且可破解的副駕駛。 只需幾分鐘即可開始並無限迭代。 一個簡單的元件,可以自動完成您的內容,就像您在 Gmail 上一樣。 ``` import { CopilotTextarea } from "@copilotkit/react-textarea"; import { CopilotProvider } from "@copilotkit/react-core"; <CopilotProvider> <CopilotTextarea/> </CopilotProvider> ``` 在這裡加星號🌟 https://github.com/RecursivelyAI/CopilotKit     ## 4. [Tolgee](https://github.com/tolgee/tolgee-platform) - 將任何上下文翻譯成任何語言! [![Tolgee](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zbsuotaz842jjgaduqe3.png)](https://github.com/tolgee/tolgee-platform) 智慧平台、快速整合、輕鬆在地化。 一個簡單的元件,可以將任何上下文翻譯成任何語言! ``` import { TolgeeProvider, T } from "@tolgee/react"; <TolgeeProvider tolgee={tolgee} fallback="Loading..." // loading fallback > <T keyName="translate_me">Translate me!</T> </TolgeeProvider> ``` 在這裡加星號🌟 https://github.com/tolgee/tolgee-platform     ## 5. [Hanko](https://github.com/teamhanko/hanko) - 對您的應用程式進行金鑰身份驗證! [![Hanko](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1j2aa3um0umgxskgau7u.png)](https://github.com/teamhanko/hanko) 美觀、可自訂的元件、SDK 和 API 可為您的登入和使用者管理提供支援。 5 分鐘內新增密碼驗證!這是該元件: ``` import { register } from "@teamhanko/hanko-elements"; const hankoApi = process.env.HANKO_API_URL; register(hankoApi); <hanko-auth />; ``` 在這裡加星號🌟 https://github.com/teamhanko/hanko     ## 6. [React Email](https://github.com/resendlabs/react-email) - 下一代書寫電子郵件 [![React 電子郵件](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ga9lcps91gv78sdy6l62.png)](https://github.com/resendlabs/react-email) 一系列高品質、無樣式的元件,用於使用 React 和 TypeScript 建立精美的電子郵件。 幫助您設計和發送電子郵件的元件! ``` import { Button } from '@react-email/button'; import { Html } from '@react-email/html'; <Html lang="en" dir="ltr"> <Button href="https://example.com"> Click me </Button> </Html> ``` 在這裡加星號🌟 https://github.com/resendlabs/react-email     ## 7. [React Flow](https://github.com/wbkd/react-flow) - 建立可拖曳工作流程的最佳方式! [![反應流程](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zqcjbtlg5d8hx69vtvaa.png)](https://github.com/wbkd/react-flow) 高度可自訂的 React 元件,用於建立基於節點的編輯器和互動式圖表 一個簡單的元件,將為工作流程呈現拖放節點。 ``` import ReactFlow, { MiniMap, Controls, Background, useNodesState, useEdgesState, addEdge, } from 'reactflow'; <ReactFlow nodes={nodes} edges={edges} onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onConnect={onConnect} > <MiniMap /> <Controls /> <Background /> </ReactFlow> ``` 在這裡加星號🌟 https://github.com/wbkd/react-flow     ## 8. [Novel](https://github.com/steven-tey/novel) - 最好的所見即所得編輯器! [![反應流程](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dz1xewgmoc7htoq6d08b.png)](https://github.com/steven-tey/novel) 概念式所見即所得編輯器,具有人工智慧驅動的自動完成功能。 一個簡單的元件,將呈現具有大量功能的概念樣式編輯器! ``` import { Editor } from "novel"; <Editor /> ``` 在這裡加星號🌟 https://github.com/steven-tey/novel --- 謝謝你們! 下週見😎

國外資深開發者,分享8個工作與生活的優化心得

國外一名資深開發者分享工作心得與技巧,與大家分享原文! 原文出處:https://dev.to/wraith/my-8-tips-for-a-better-life-as-a-developer-1hfg --- 我擔任軟體開發人員已經有 8 年多了,從我自己的經驗以及從一些非常有才華的人那裡學到了很多東西。在這篇文章中,我想分享一些真正讓我的體驗變得更好、更愉快的事情。 ## 1. 找一個您喜歡工作的地方 ![三個人坐在咖啡店裡用電腦工作,微笑。](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/shosztzzfmpjuf7ksr5c.jpg) 您的環境對您的生活貢獻很大。它可以增加或減輕壓力,幫助您集中注意力或分散注意力,讓您感到安全或不安全等等。因為它在我們每個人的生活中都扮演著不可或缺的角色,所以我認為從這裡開始是合適的。 無論您是在辦公室還是遠端工作,您很可能可以採取一些措施來找到一個讓您感覺「合適」的地方。我說「對」是因為這裡每個人都會有所不同。有些人想要感到舒適和「賓至如歸」。其他人想要一個不太舒適的區域,而是真正讓他們「進入狀態」並集中註意力的區域。 多年來,我嘗試了很多不同的地點,只是為了看看什麼對我有用。我坐在陽台上,享受早晨涼爽的空氣,喝著一杯熱咖啡。我確實坐在桌子底下,身上蓋著毯子。我坐在壁櫥、角落、咖啡店、餐廳、酒吧、汽車、公園、餐桌和樓梯井裡。透過所有這些實驗,我已經能夠找到在我需要時為我提供所需的地方。如果我需要集中註意力,我就需要獨處。某處有一扇可以關閉的門,但沒有窗戶讓我注意到有人走過。當我太舒適時,就像依偎在柔軟的沙發上的毯子裡時,我的工作效果就不太好。如果我需要改變節奏,或者只是需要和人們在一起,我發現我真的很喜歡坐在不太擁擠的小酒吧或餐廳裡。我可以在某個地方點一杯飲料和一份開胃菜然後工作,但周圍仍然有幾個人。 所以我鼓勵你嘗試幾個地方。找出什麼對你有用,同樣重要的是,找出什麼對你沒用。如果你找不到地方,你總是可以花一點力氣去打造你想要的地方! 「正確」對你來說意味著什麼? ## 2. 投資硬體 ![黑暗房間裡一張配有高科技設備的桌子,LED 照亮空間](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7knnfnk29bpe02gibac4.png) 作為軟體開發人員,我們使用的硬體數量非常多。可以說,我們使用鍵盤和辦公椅之類的東西比生活中任何其他物品都多。當然,我們可以使用任何舊鍵盤來完成工作,我們可以坐在任何椅子上。但我發現,對「更好」的硬體進行一點投資會對我的工作體驗產生很大的影響。 ### 椅子 如果您在工作時坐著,並且您只想投資一件東西,那麼它絕對應該是您的椅子。一張既提供舒適又提供支撐的椅子確實可以大有幫助。從您可以坐多久並集中註意力而不會感到不舒服,到日常生活中背部、頸部和肩膀的感覺,您的椅子對您的整體健康和福祉有很大影響。因此,一定要找到一款好的產品,而不要只滿足於會導致不良姿勢的產品。 我個人使用 [Secretlab Titan Evo(蝙蝠俠主題)](https://secretlabchairs.ca/products/titan-evo-2022-series?sku=R22PU-Batman),幾年來我對它非常滿意。與許多高端桌椅相比,價格還不錯。 ### 鍵盤 僅次於椅子(但相差不多)的是鍵盤。輕鬆地成為我們每天工作中互動最多的工具。那裡也有很多選擇,因此無論您的個人喜好如何,很可能有一些東西可以滿足您的需求。 每個人選擇合適的鍵盤都有很大不同。有些人喜歡低調的鑰匙而不是機械鑰匙。有些人需要整合 USB 連接埠。成本、人體工學、有線或無線、可自訂的按鍵和開關、背光、可配置的 LED、支援配置按鍵佈局、高度和大小、按鍵數量,這樣的例子不勝枚舉。尋找適合您的鍵盤無疑是一段旅程,但我強烈建議您繼續下去。當然,我們可以使用任何鍵盤來完成我們的工作......但我保證,如果您嘗試一下,找到「正確的」鍵盤將使您作為開發人員的一天和體驗更加愉快。 我使用 [Moonlander Mark 1](https://www.zsa.io/moonlander/),絕對💙它!分離式設計確實幫助我不再那麼無精打采,也幫助消除了我長期以來的肩膀和手腕疼痛。再加上那些櫻桃棕色的開關聽起來很漂亮😍! ### 滑鼠 談論鍵盤就不能不談論它們的助手——滑鼠。就像鍵盤一樣,市面上有許多不同類型的鍵盤,每個人都會有自己的偏好。幸運的是,即使是半像樣的滑鼠也有相當低的價格,因此嘗試一些滑鼠來找到適合您的滑鼠相對容易。但與此處的所有其他專案一樣,投入一點時間和金錢即可對您的體驗產生積極影響。 我的老鼠是 [ZLOT 垂直遊戲滑鼠](https://www.amazon.com/gp/product/B07T3PFWCB?th=1)。它是一款較輕(重量)的滑鼠,但具有良好的人體工學感覺和響應能力,我已經喜歡了很長一段時間了。 ### 螢幕 這絕對是一個可選專案,但我發現它讓我的工作更加愉快。並非每個人都需要外接顯示器。有些人實際上更喜歡直接使用筆記型電腦工作。但如果您確實喜歡使用外部顯示器,這是一項可以產生巨大影響的投資。 遺憾的是,由於多台 4k 顯示器在 Mac 上工作出現問題,我放棄了多顯示器設置,現在使用 [Sceptre 35" 曲面顯示器](https://www.sceptre.com/Monitors/2K-4K-Series/C355W-3440UN-35-Curved-Monitor-product1176category12category98.html)。它有很多空間,所以我仍然可以在一個螢幕上打開大量視窗。 ### 耳機 耳機也是可選的(有些人可能會反對這一點😝),但它們的好處怎麼強調都不為過。從減少干擾到幫助您集中註意力,一副好的耳機可以大有幫助。就像我列出的大多數專案一樣,每個人的偏好都會有所不同。但是,投入一點時間和金錢來尋找一雙適合您的好鞋,確實可以將您的遊戲提升到一個新的水平。我認識的許多人都尋求良好的降噪效果,而且它們必須輕盈舒適,這樣才能一次佩戴幾個小時。 我個人喜歡使用 Beats。我曾經使用[Studio3](https://www.bestbuy.ca/en-ca/product/beats-by-dr-dre-studio3-over-ear-noise-cancelling-bluetooth-headphones-black/11534527 )但是當我必須開始戴眼鏡時,我不喜歡這些耳機給我的鏡框帶來的壓力,所以我改用了[Beats Fit Pro](https://www.beatsbydre.com/earbuds/beats-fit-pro?sku=MK2F3) 並且對它們非常滿意。我已經連續戴了 8 個小時,效果非常好。它們輕巧、舒適、音質好,並且在我慢跑和運動時表現良好且穩定。 您使用什麼硬體?您夢想的硬體是什麼? ## 3. 找到您*喜歡*使用的工具 ![應用程式牆的螢幕截圖,應用程式圖示上有有趣的表情符號臉孔](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/clgqlfokffwpu57wnkr9.png) 除了硬體之外,作為開發人員,我們還使用許多軟體工具來完成我們的工作。有些我們別無選擇,但也有很多我們可以選擇,找到您真正喜歡使用的工具確實可以讓您的日常體驗變得更好。即使只是擁有一個可以配置為您喜歡的外觀的工具也可以產生積極的影響。 我在這裡想強調的不是找到每個人都使用的工具,因為他們可以做各種各樣的事情。更多的是尋找您真正「喜歡」和「期待」使用的工具來完成工作。即使它們不能完成其他工具可以完成的所有奇特的事情,如果您確實希望使用其他工具,那就使用它!擁有我們積極喜歡的工具確實會為我們的生活增添很多積極性。 多年來,類似的工具有很多,但這裡有一些工具為我的日常生活帶來了很多樂趣: - Giphy Desktop app - 用 gif 回覆取代無聊的文字,讓 Slack 訊息變得生動起來。 - Raycast - 這已經取代了我 Mac 上的 Spotlight。透過專業版,我可以存取 ChatGPT 4...因此,只需一個快速鍵盤快捷鍵,我就能輕鬆掌握 AI。對我來說遊戲規則改變者! - Obsidian - 雖然這已經是一個流行的筆記應用程式,但我花了一些時間編寫了一些腳本來為我自動化工作,它完全改變了我記下所有筆記並跟踪我需要做的所有事情的方式。 - Arc browser - Arc 花了整整 1 天的時間才成為我的主要瀏覽器。現在,當我測試瀏覽器對我正在建立的某些功能的支援時,我只使用其他瀏覽器(在我的桌面上)。 - Habitical - 獲得徽章、成就和一般遊戲化讓我非常有動力,所以這個待辦事項應用程式讓我管理和執行任務變得更加有趣! 有哪些工具可以為您的日常開發生活帶來樂趣? ## 4. 設定目標 ![一台打字機,上面印有一張伸出的紙上的「目標」](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vcsabk75mtb2o8dlwbt3.jpg) 我知道這聽起來很明顯,而且我相信我們都從無數其他來源聽到這一點。但您可能會驚訝地發現有多少人沒有為自己設定目標。不相信我?向你的任意 2 到 3 個鄰居詢問他們目前正在努力實現什麼目標。當我問這個問題時,經常得到的只是聳聳肩,然後回答「沒什麼」。 僅僅設定目標也是不夠的。你也必須定期考慮它們。有些方法建議將它們寫下來並放在鏡子上或您經常看到它們的地方。這個方法對我個人來說沒有效果,但也許對你有用?對我來說有效的方法是每天早上開始工作前坐下來15 分鐘,並重點思考我的目標、我所有的待辦事項以及日曆上的所有事情(是的,我實際上在日曆上留出15分鐘的時間)這個,並強迫自己堅持這個時間)。在這段時間裡,我思考我的目標,並找出我今天可以做的一件小事,讓我離實現每個目標更近一步。 例如,如果我的目標是在家人來過感恩節之前清理車庫,我會想,「我今天可以做哪一件小事來實現這個目標?」。有時答案特別小…「掃到工作台下面」。其他時候我可能會更有動力,或者我有更多的可用時間,這可能是更大的事情。無論如何,請花一些時間考慮您今天可以採取的一項行動來實現該目標。 當我這樣做時,我的大腦中會發生一些事情。我發現自己感覺更有成就感和更樂觀。當然,完成目標可能是一條漫長的道路(如果它是一個大目標),但是知道我離我想要完成的事情更近了,這對我的日常生活產生了積極的影響,並讓我能夠完成的事情比我想像的還要多。 無論大小,給自己設定目標。然後定期思考它們,並採取許多微小的行動,以朝著前進邁出一步。我保證這會為您的生活帶來美好的事物! 現在您正在努力實現哪些目標? ## 5. 保持好奇心並了解*為什麼* ![視窗上有一個標誌,上面寫著「#becurious」](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/42zs3m4tlzbcilh338nd.png) 很多人對編碼專案中的完成方式感到沮喪或評判。我肯定去過那裡! - “為什麼有人選擇這項技術?!對於這個用例來說,其他技術要好得多...” - “為什麼有人會寫這樣的程式碼?!” - “如果我們不做 X 而只是做…,事情會好得多” 這些聽起來很熟悉嗎? 儘管事情有時會令人沮喪,但在軟體開發中,做出的每個決定背後幾乎總是有一個「原因」。這是最好的選擇嗎?也許不是……但做出這樣的選擇還是有原因的。 我曾經對事情的現狀感到沮喪,然後在嘗試解決問題時感到沮喪,然後在遇到障礙時感到沮喪。但最終,事情突然發生了,我沒有感到沮喪,而是開始尋找這些事情發生的原因。背後的*原因*是什麼。當我養成「尋找原因」而不是「想知道為什麼不」的習慣時,我的好奇心變得更強。我發現我正在尋找更多的訊息,更徹底地學習和理解事物,更多地同情與我一起工作的人,最終,沮喪的感覺減少了很多。 現在,我的經歷更加積極了。無論我是重構一段複雜的程式碼,試圖找到解決惱人問題的方法,還是為新工作學習全新的程式碼庫,我實際上更喜歡這個過程,因為我只是好奇並想知道「為什麼」。 最近一次讓您真正感到沮喪的編碼*事情*是什麼?您知道*為什麼*會是這樣嗎? ## 6. 為重點工作劃出日曆 ![一週中每天 2 小時的日曆條目顯示「焦點時間」](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/13x844h65h98y6c78bsk.png) 這說起來容易做起來難,具體取決於您的工作地點,但它會對您的開發人員生活產生驚人的影響! 您是否曾經在該區域中,只是編寫程式碼來建立該新功能,然後「*叮!*」有人向您發送了一條緊急的 Slack 訊息?或是有人拍拍你的肩膀問你問題?您解決了乾擾問題,然後返回螢幕,然後您就失去了所有註意力?如果沒有……我願意賭很多錢,你會在職業生涯的某個時刻這麼做。 「在區域中」或進入「心流」的概念是一個已經被研究和寫了很多的主題。我強烈建議您查看一些有關該主題的文章和書籍,因為這是一個非常有趣的主題(至少對我來說是😃)!其中許多研究都表明,處於心流狀態是多麼有益,而且在中斷後可能需要 20 分鐘以上才能恢復到那種精神狀態!因此,找到讓自己進入這種心態並保持這種狀態的方法非常重要! 我發現讓自己進入這種狀態的最佳方法之一就是在日曆上劃出大量時間專門用於「專注工作」。一開始這可能是一個挑戰,讓人們在嘗試聯繫之前檢查您的日曆或 Slack 狀態,並幫助每個人了解您將在焦點時間結束後立即回覆他們。但最終人們會明白過來,並且回報是巨大的!別忘了在這段時間關閉通知! 不過這裡有一些提示...... - 接受有時會出現緊急事務並需要更高優先順序的事實。這就是生活,我們只能隨波逐流……但這不該成為「常態」。 - 拍攝 2-3 小時的片段。少於這個數量會讓人覺得不夠,但超過這個數量,人們就會被迫更頻繁地打斷你。請記住,其他人也有重要、緊急的事務,在當今的工作環境下,讓他們等待半天以上才能獲得地址確實不公平或不合理。 - 在你最有生產力的時間安排這些時間段。對我來說,早上 6 點到 10:30 左右我的工作效率最高。所以我通常會嘗試將我的專注時間安排在這些時間裡。 您發現一天中的什麼時段您的工作效率最高? ## 7. 讓 PR 小一點 ![GitHub 審核標題的螢幕截圖,顯示 3 個檔案已更改,總共進行了 35 項更改](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jf7cy31tmzjjfz9wz2cn.png) 我喜歡這個,並且在過去一年左右的時間裡它已經成為我的首要任務。 事實證明,保持 Pull 請求(或 GitLab 人員的合併請求)較小有很多積極的好處。發布的錯誤更少,我們審查程式碼的時間更少,功能的推出速度更快,僅舉幾例。所有這些不僅使我們的產品變得更好,而且我發現它也極大地改善了我作為開發人員的體驗! 透過專注於較小的變化,我發現我可以更徹底地思考問題,考慮到在較大變化的混亂中可能被忽視的用例。我能夠更快地將變更納入審查,我的團隊成員能夠更快地審查我的程式碼,因為我只佔用了他們5 分鐘而不是2 小時的時間,並且在審查期間,我收到的程式碼要少得多變更請求。因此,更好的程式碼將會出現,我可以繼續花更多的時間來建立新的東西,而不是必須解決一堆被遺漏的錯誤。 另一方面,審查小型 PR|MR 比大型 PR|MR 更令人愉悅。您是否曾經需要審查某人的 PR|MR,其中包含數千個更改、跨越 20 多個檔案以及應用程式的多個區域?當你這樣做時,你的第一個反應是什麼?您是否對參與並開始審核感到過於興奮?或者,也許您感到“呃”,於是推遲了會議,因為距離下一次會議只有 30 分鐘,而您可以在這段時間內完成其他事情? 當審查大型 PR|MR 時,通常會失去很多細節(或至少受到較少的關注),最終,大多數人會達到「審查盲目性」或「審查疲勞」的地步,事情開始被忽視,或者審稿人必須離開一段時間,稍後再回來。這一切都會導致審核過程花費更長的時間、效率更低,並導致提交更多的變更請求。更不用說所有團隊成員都有的不滿情緒了。 自從我開始將此作為自己的優先事項,並與團隊成員一起努力讓他們也這樣做時,我注意到我在 PR|MR 方面的經驗明顯改善了。我更願意在會議之間跳出一些評論,我不得不要求更少的改變,而且我不會在需要離開並重新振作起來之後感到精疲力盡。就連我的計劃也變得更準確了! 總而言之,我強烈向大家推薦這個。如果您想了解更多關於這樣做的好處,我建議您查看 [LinearB 部落格](https://linearb.io/blog) 以及 [Dev Interrupted 播客](https://linearb.io/dev-interrupted/podcast).他們談到了一些很棒的觀點,我發現這些觀點確實對工程領導者和團隊有幫助! 你曾經審查過的最糟糕的公關是什麼? ## 8. 寫下一切! ![有人在筆記本上寫筆記](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yeqff10xv6ej22xk22w8.jpg) 我的最後一個建議是我在去年開始做的事情,在閱讀了[如何做智慧筆記](https://www.amazon.ca/How-Take-Smart-Notes-Technique/dp/3982438802)和[把事情做好](https://www.amazon.ca/Getting-Things-Done-Stress-Free-Productivity/dp/0142000280)它對我的生活產生了驚人的影響。 當我學到新東西時,我會把它寫下來。即使只是一小段描述我學到的東西。當出現新任務時,無論大小,我都會把它寫下來。在會議期間,如果分享想法、給予回饋、提出問題,所有這些都會被記錄下來。如果我對某事有一個隨意的想法,或者一個頭腦發熱的想法……你猜對了……它會被寫下來。然後,每當我有幾分鐘空閒時間時,我都會先看筆記,而不是瀏覽社群媒體。我盡可能回顧它們,這強化了我腦海中的訊息,但也幫助我將不同的想法聯繫在一起,這往往會產生一個全新的想法。 透過這樣做,我發現我對事情的記憶更加徹底。如果我不能,我有記錄並且可以將其調出!它使我能夠完成更多的工作文件,而且我甚至在任何給定時間都有 4 或 5 篇部落格文章正在編寫中!遺漏的事情少了很多,而且我能夠完成更多的事情。 我最近開始了一份新工作,透過使用這種方法,人們已經來找我詢問我是如何做到這麼多的!秘密醬汁?全部寫下來並將其加入到系統中。 這對我來說改變了遊戲規則,我只需要鼓勵其他人也這樣做,因為我真的相信這可以使他們的生活受益匪淺! 你用什麼方法來記住和分享你學到的東西? ## 結論 在過去 8 年多的軟體開發人員和工程師工作中,我學到了很多。我經歷過好時光和壞時光,並一路走來學到了一些非常有用的人生課程。透過找到我喜歡工作的地方,在我的硬體上投入更多的時間和金錢,找到我「喜歡」使用的工具,設定目標,保持好奇心並專注於“為什麼”,定義專注工作的時間,專注於保持PR 較小,並寫下我能寫下的一切,我可以誠實地說,我的開發者體驗得到了極大的改善。 我非常希望這些技巧中至少一兩個能改善您的體驗。

不是共產黨,但是審查低質量雜訊很重要!自己寫一個JS腳本過濾!

本文轉自:https://ithelp.ithome.com.tw/articles/10338948 ## 前情提要 資訊大爆炸。 有時候我們瀏覽技術文章,不一定真的是想學深奧的高級技術。 然而劣質低端的文章充斥著,則會降低我們學習的效率、甚至變成噪音與雜訊,干擾我們的思緒。 因此針對某些洗文或是質量很低的作者,我們必須列為思想犯, 否則會降低閱讀質量,平白浪費自己的時間、平台的版面、上網的電力、看到垃圾資訊的副作用等等.... ## 構思來源 如果有個思想審查警衛可以:**去除那些垃圾低端,稱不上技術文章的雜訊。** 以確保未來瀏覽文章的時候,不會再被洗文打擾, 也可以針對不喜歡的主題去封鎖,讓時間與精神更能專注於自己想要學的資訊。 阻止一些垃圾就是喜歡把自己尚未整理的白痴內容一直丟上來, 什麼都還不懂,把技術文章當成個人日記簿,寫一堆自我囈語、無病呻吟, 每天大量狂發文章,昭告天下以為這就是努力,欺騙自己也浪費別人的人生。 ## 「思想審查警衛」出動! ## 功能 1. 把頭像屏蔽 2. 加上思想通緝犯、紅字與刪除線 3. 新增封殺按鈕 4. 版面通知封殺名單與文章數 5. 透過ajax確認某id的最新ID ## 效果截圖 ![](https://i.imgur.com/kgUYJbl.png) 此截圖僅是腳本示範,跟其使用者無關, 本人沒有任何覺得此使用者發的文章是差勁的意味,我認為非常上進、值得學習。 ![](https://i.imgur.com/G27Ea2F.png) 此圖也只是隨機挑user使用,純粹作為範例用途,不代表我個人意見。 ## 腳本下載 https://greasyfork.org/zh-TW/scripts/477283-%E6%80%9D%E6%83%B3%E7%8A%AF%E5%B0%81%E6%AE%BA ## 原理說明 鄭重聲明,這個示範真的毫無任何私人意味,此腳本也只是針對不同的主題去隱藏, 例如我想學python就不想看到JS的文章,因此使用此工具幫忙隱藏罷了。 取名做思想警察、比喻成清除垃圾等都只是文學上的趣味。 請勿當真Ꮚ・ꈊ・Ꮚ 這次的技術可說比較難,認真難很多!但是趣味性以及功能性是無比的超越! 可以說幾乎是我寫系列文以來,最頂、最派的一篇! 不過很多觀念已經出現過,在【前端小試身手】系列裡面,每次的腳本都是主打實用, 因此cookie或localstorage這種技術當然都會運用到。 ## JS原始碼 ``` // ==UserScript== // @license MIT // @name 👮思想犯封殺 // @namespace http://tampermonkey.net/ // @version 0.1 // @description 把廢文製造機轟出去 // @author You // @match https://ithelp.ithome.com.tw/articles* // @match https://ithelp.ithome.com.tw/users/* // @icon https://www.google.com/s2/favicons?sz=64&domain=ithome.com.tw // @grant none // @run-at document-end // ==/UserScript== let URL = window.location.href; let ArticleSite = "https://ithelp.ithome.com.tw/articles?tab=tech" let UserSite = "https://ithelp.ithome.com.tw/users/" // 判斷URL的開頭部分 if (URL.startsWith(ArticleSite)) { //文章頁執行清理垃圾程序 CleanGarbage(); } else if (URL.startsWith(UserSite)) { UserCheck(); } else { console.log("這邊不執行腳本"); } // 餅乾儲存的機制函數------------------------------------------------- function setListInCookie(list) { document.cookie = 'myList=' + JSON.stringify(list) + '; expires=Wed, 31 Dec 2099 23:59:59 GMT;'; } // 從 Cookie 中獲取 list function getListFromCookie() { var cookieValue = document.cookie.replace(/(?:(?:^|.*;\s*)myList\s*\=\s*([^;]*).*$)|^.*$/, "$1"); return JSON.parse(cookieValue) || []; } function CleanGarbage(){ // 從本地存儲中獲取數據 var myListData = localStorage.getItem("myList"); // 解析數據到變量 list var list = myListData ? JSON.parse(myListData) : []; //list = getListFromCookie()||[]; // 儲存要刪除的字符串名單 // 找到所有CLASS是"qa-list__info-link"的<a>元素 var linkElements = document.querySelectorAll('.qa-list__info-link'); var removedCount = 0; // 初始化已清除的垃圾數量 for (var j = 0; j < list.length; j++) { // 遍歷這些<a>元素,確保文本內容包含"伍貳捌",然後刪除其父元素 for (var i = 0; i < linkElements.length; i++) { if (linkElements[i].textContent.includes(list[j])) { // 開始向上查找父元素 var parentElement = linkElements[i].parentElement; while (parentElement) { // 如果找到具有"classname"為"qa-list"的<div>元素,則刪除它 if (parentElement.classList.contains('qa-list')) { parentElement.remove(); removedCount++; // 增加清除的數量 console.warn('抓到"'+list[j]+'"這位思想犯'); break; // 找到並刪除後,結束循環 } parentElement = parentElement.parentElement; } } } if (removedCount>0){ // 顯示已清除的垃圾數量 console.log('已清除他的 ' + removedCount + ' 篇垃圾');} removedCount=0; } } //------------------------------------------------------- // 為了防止五百八改名,我們針對他的ID去ajax得到他最新的名稱 function FindBitch() { // 使用 Fetch API 獲取指定 URL 的內容 return fetch("https://ithelp.ithome.com.tw/users/20163468") .then(response => response.text()) .then(data => { // 創建一個臨時 div 元素以容納頁面內容 var tempDiv = document.createElement("div"); tempDiv.innerHTML = data; // 查找 class 為 "profile-header__name" 的元素 var profileNameElement = tempDiv.querySelector(".profile-header__name"); if (profileNameElement) { // 刪除元素內的所有 <span> 元素 var spanElements = profileNameElement.querySelectorAll("span"); spanElements.forEach(function(span) { span.remove(); }); // 讀取元素的文本內容,去掉前導和尾隨空格 var text = profileNameElement.textContent.trim(); // 返回處理後的文本內容 return text; } else { return "未找到元素"; } }) .catch(error => { console.error("發生錯誤: " + error); return "發生錯誤"; }); } //------------------------------------------------------- function UserCheck(){ //轉換資料從餅乾到localstorage var currentCookieValue = getCookie("myList"); // 2. 存儲數據到本地存儲 if (currentCookieValue) { var list = JSON.parse(currentCookieValue); // 存儲到本地存儲 localStorage.setItem("myList", JSON.stringify(list)); }else{ FindBitch() .then(text => { let FirstKill = [text]; setListInCookie(FirstKill); }) .catch(error => { console.error("找不到五百八:", error); }); } // 刪除不需要的ID document.querySelector('.profile-header__account').remove(); //封殺按鈕------------------------------------------------- // 找到具有class為"profile-header__right"的元素 var profileRightElement = document.querySelector('.profile-header__right'); var pullRightElement = profileRightElement.querySelector('.pull-right'); // 創建一個新按鈕元素 var BlockBtn = document.createElement('button'); BlockBtn.textContent = '封殺'; // 添加樣式和類名到按鈕 BlockBtn.style.marginTop = '10px'; BlockBtn.style.width = '100%'; BlockBtn.className = 'btn btn-trace trace_btn_border BlockBtn'; // 將按鈕元素添加到"pull-right"元素內部 pullRightElement.appendChild(BlockBtn); // 通緝犯名單的cookie------------------------------------------------ // 從 Cookie 中加載 list(例如,頁面加載時) list = getListFromCookie()||[]; let UserBlock = document.querySelector('.profile-header__name'); let text = UserBlock.textContent.trim(); // 如果使用者已經在封殺名單內的判斷,已存在或不存在 if (list.includes(text)) { BlockStart(BlockBtn); } else { // 針對封殺按鈕進行監聽事件 BlockBtn.addEventListener('click', function() { list.push(text); setListInCookie(list); //先加入到名單內,然後再執行封殺事件 BlockStart(); // 輸出到控制台 console.log('黑名單新增:' + text); //本地儲存機制----------------------------- let currentCookieValue = getCookie("myList"); let list2 = JSON.parse(currentCookieValue); // 存儲到本地存儲 localStorage.setItem("myList", JSON.stringify(list2)); }); } } // ------------------------------------------------ //封殺事件的函數 function BlockStart(){ let BlockBtn = document.querySelector('.BlockBtn'); BlockBtn.textContent = '已封殺'; BlockBtn.disabled = true; BadText(); BadImg(); } //封殺事件函數裡面的細項函數 function BadText(){ // 標記這傢夥是垃圾------------------------------------------------- let UserBlock = document.querySelector('.profile-header__name'); let newHeading = document.createElement('h1'); newHeading.textContent = '思想通緝犯'; // 把思想通緝犯這幾個大字加上去 UserBlock.parentElement.insertBefore(newHeading, UserBlock); UserBlock.style.textDecoration = "line-through"; UserBlock.style.color = "red"; } function BadImg(){ //圖片進行網點作業XD------------------------------------------------- var originalImage = document.querySelector('.profile-header__avatar'); // 創建一個包含交叉紅線的覆蓋層 <div> 元素 var overlayDiv = document.createElement('div'); overlayDiv.style.position = 'absolute'; overlayDiv.style.width = '150px'; overlayDiv.style.height = '150px'; overlayDiv.style.background = 'linear-gradient(45deg, black 50%, transparent 50%), linear-gradient(-45deg, black 50%, transparent 50%)'; overlayDiv.style.backgroundSize = '5px 5px, 5px 5px'; overlayDiv.style.backgroundPosition = '0 0, 0 2px'; // 將覆蓋層疊加到圖片上 originalImage.parentNode.appendChild(overlayDiv); // 設置覆蓋層的位置,以與原始圖像對齊 overlayDiv.style.top = originalImage.offsetTop + 'px'; overlayDiv.style.left = originalImage.offsetLeft + 'px'; // 設置覆蓋層的z-index,以確保它在圖片上方 overlayDiv.style.zIndex = '2'; } ``` ## 觀念筆記 這個腳本開發足足花了我一整個晚上,將近八小時之久。 有趣的是,其中為了進行測試才選某些user當作隱藏對象,否則腳本執行上會出錯。 細心的人若觀察原始碼,也會發現裡面有個firstKill, 那是必須要的段落,先設置好cookie的首要內容物,才有辦法繼續操作下去( ิ◕㉨◕ ิ) 也就是初始化的概念XD 另一個有趣的點是,為了防止使用者改名導致腳本出錯,我甚至不惜再寫一段ajax, 去更新一下ID,這樣不管人家怎麼改,都逃不了, 要改成「別抓我」也沒用,這個腳本都還是可以run。 ## 心得後記 我只能說這篇是自從「備份IT幫發文、一眼全覽」最強的JS教學文章! 超派,真的不騙( メ∀・) 有些人喜歡看前端小試身手,有些人喜歡前端動手玩創意; 其實這兩個系列的本質都是JS的教學,是可以互相連接的,但也有很多不同的重心。 這個系列就是以腳本為主,重點在於創意與發想,打到使用者痛點。 【前端動手玩創意】則是以建構網站為起點, 任何元素與概念都會變成網頁上的一部分,算是比較基礎工的建立。 如果對JS的強大感興趣,那麼可以把這兩個系列交互看,反覆的閱讀、實際動手操作, 這樣一來的學習非常踏實,甚至比YT學習都來的高效率、實際。 尤其此系列都是原創發想的腳本,當然超強! 喜歡記得關注,未來還有更多超酷的前端內容可以玩,下課⧸⎩⎠⎞͏(・∀・)⎛͏⎝⎭⧹

挑戰串接CodeLove的API

成品連結:https://codingdark.github.io/program/2023/09/18/API-Test.html ##第一步 架部落格 最初看到站長的貼文,提供了本站的API 並且鼓勵大家自架部落格,來嘗試串API 看到文章的當下,覺得有點難度(沒用過github page,API也不熟) 不過看到站長提供的關鍵字`setup a personal blog with github pages` 最終還是決定先google看看 查了之後,發現近年的gitbub簡化了很多 都可以自動部署,根本就是一鍵架站 外加原始碼開源,很多東西都能自己改 所以光是部落格就玩了一天XD 因為本站為CodeLove 愛寫扣 我就創了一個CodingDark 闇寫扣 表示致敬本站 & 本人的中二風格 ##第二步 串API 因為不熟的關係,所以決定先隨便串 呼叫API之後,把data印在console.log 大致上看了一下資料格式 使用上其實就類似陣列,非常方便 沒有想像中的難 確認API可以正常呼叫後 陸續加入一些功能 比方說,用Table把文章列表排整齊、加上[Read more]按鈕 先讓json資料,轉換成網頁能呈現出來的[資訊] ##第三步 程式碼優化 到這邊為止,網頁的畫面已經差不多定型了 剩下的就是回頭檢視程式碼 考量到後續維護 盡可能把重複的程式碼,包裝成function 或是把一群散亂的變數,包裝成object 最後,為了方便擴充文章列表 將原本是寫死的HTML Dom 改成動態產生 目前的部落格頁面 點進去會撈出站長、Tony,以及我的文章列表 後續若想要列出其他使用者的文章 只需新增`setTable(userAccount)`即可 ##結尾 感謝站長提供有趣的API 讓大家可以有練習的機會 雖然目前我在工作上,沒接觸過API 但經過這次的練習,以後若是真的有需要用到 可以更快上手

Rust 新手文章:記憶體管理機制簡介

您是否想過當您**執行 Rust 程式**時**RAM**會發生什麼情況**?您編寫程式碼的**方式會如何干擾系統中的許多其他事物? 這篇文章將幫助您了解更多關於 *管理記憶體* 和 **RUST 如何運作** 的資訊。 原文出處:https://dev.to/canhassi/how-rust-memory-management-work-to-beginners-622 ## 1. Stack and Heap 在了解 rust 的作用之前,您必須先了解一些概念。一般來說,我們有兩種類型的內存,稱為:**堆疊和堆**。現在我們來介紹一下他們。 ### 1.1 記憶體:Stack 堆疊,顧名思義,**工作原理就像堆疊**,遵循**“後進先出”(LIFO)的原則。**也許分步驟解釋會更容易: *想像一下**一堆盤子**; *您放入的**第一道菜**是**最後取出的**; * 當**函數被呼叫**時,一塊記憶體被**「堆疊」在棧頂; * 當**函數結束**時,該區塊**“unstacked”**,釋放該記憶體。 通常,**編譯器**(在編譯時)知道將儲存在堆疊上的**值**,因為它知道需要儲存多少記憶體。此過程**自動**發生,所有值都會從記憶體中刪除。 下面是一個例子: ``` fn main() { let number = 12; // at this moment the variable has created println!("{}", number); // 12 } // When the owner (main function) goes out of scope, the value will be dropped ``` 在 Rust 中,我們只需使用「{}」即可建立一些作用域,這會在堆疊中加入具有有限生命週期的層。當您離開該特定*範圍*後,記憶體將被清除,您將遺失相關資訊。一個很好且簡單的例子是: ``` fn main() { { let number = 12; println!("{}", number); // 12 } println!("{}", number); // Cannot find value `number` in this scope } ``` ### 1.2 記憶體:Heap 簡而言之:**堆**記憶體是一個空閒記憶體空間,用於分配可能更改的資料。 想像一下,您需要在啟動程式後**儲存一些變數**,該變數在編譯時沒有已知的固定大小,因為它可能有大小變化或是記憶體中的直接分配。 如果上述可能性之一匹配,我們就知道我們有 **堆** 內存,而不是 **堆疊**。堆擁有更**靈活的記憶體**和更大的空間。看一看: ``` let number = Box::new(12); // alocate a integer in heap let name = String::from("Canhassi"); // alocate a String in heap ``` 在 Rust 中,我們有兩種字串「類型」:「&str」和「String」。 * **&str**:根據所寫的文字有固定的大小; * **字串**:具有可以增加、減少和刪除的大小。 ……這就是為什麼 `String` 儲存在堆上,而 `&str` 儲存在堆疊上。 釋放堆記憶體的一種方法是:當儲存堆上某些內容的**變數離開函數的作用域(到達函數末端)時,它將以相同的方式釋放作為堆疊。 好了,現在我們對這兩種記憶體類型有了一個清晰的認識,但是堆疊和堆在管理記憶體方面有什麼區別呢?讓我們看看這些差異吧! ## 2. 借用檢查器 借用檢查器是 Rust 編譯器的**部分**,它**檢查並確保**所有權、借用和生命週期**規則得到尊重**。 老實說:一開始我在理解它是如何運作的方面遇到了一些問題,我發現這在新的 Rustaceans 中很常見。但別擔心,我的朋友。我會用最好的方式教你。但首先,讓我們先來看看下面的程式碼: ``` fn main() { let name = String::from("Canhassi"); // Creating a string variable print_name(name); // calling the print_name function passing the variable println!("{}", name); // Error: name borrowed to print_name() } fn print_name(name: String) { println!("{}", name); // print "Canhassi" } ``` 如果您使用該程式碼執行編譯器,您將看到以下錯誤: ``` borrow of moved value: name ``` 當我們呼叫“print_name”函數時,“name”變數將被**移動到另一個作用域**,並且該作用域將成為它的**新所有者**。並且所有者的規則超出範圍將再次應用。借用檢查器確保**一旦所有權轉移**,原始變數**不能再用於**來存取該值。這發生在上面的程式碼中。 使用原始變數的另一種方法是使用類似的引用。 ``` fn main() { let name = String::from("Canhassi"); // Creating a string variable print_name(&name); // calling the print_name function passing the variable println!("{}", name); // print "Canhassi" } fn print_name(name: &String) { println!("{}", name); // print "Canhassi" } ``` PS:這些**借用檢查器的規則僅適用於**堆中指派的物件**。 ## 3. 錯誤預防 借用檢查器對於確保 Rust 記憶體安全而無需[垃圾收集器](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)) 至關重要。 在 C 和 C++ 等其他語言中,我們(作為開發人員)必須使用某些函數手動釋放記憶體。 C++ 以允許記憶體管理錯誤而聞名,包括[記憶體洩漏](https://en.wikipedia.org/wiki/Memory_leak)。 C++本身不會導致記憶體洩漏。相反,**C++ 為程式設計師提供了大量的靈活性**和控制力,如果使用不當,這種**自由可能會導致錯誤**。 一個著名的錯誤是**未定義的行為**,例如,想像一個函數傳回這樣的變數的引用 ``` fn main() { let number = foo(); // calling foo function } fn foo() -> &i32 { let number = 12; // creating a var number &number // try return a reference of var number } ``` 程式碼不起作用,因為 Rust 編譯器對記憶體管理有限制規則。我們不能回傳 var `number` 的引用,因為這個函數的作用域將會消失,而 var `number` 將會消失,所以 Rust 不會讓這種情況發生。在 C++ 中我們可以做到這一點,並且它允許臭名昭著的記憶體洩漏。 我認為知道 Rust 編譯器避免了這種類型的錯誤真是太酷了...如果這個主題對您來說是新的,我可以說內存洩漏可能會花費很多錢並且確實很難修復它,因為絕不只有一次內存洩漏。 其他範例是,**雙重釋放**,當您嘗試釋放相同物件兩次(例如在 C 程式碼中)時,就會發生這種情況。 ``` char* ptr = malloc(sizeof(char)); *ptr = 'a'; free(ptr); free(ptr); ``` 這個主題非常廣泛,當您使用其他語言時,很可能會產生類似的錯誤。但是,我會讓您自己進行研究,並確保在這篇文章的評論中告訴我更多! ## 4。結論 我寫這篇文章的目的是以更一般的方式展示記憶體管理如何與 Rust 配合使用。但我建議您閱讀《Rust 程式語言》一書的第 4 章( https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html )來獲得更完整的知識。在那裡您將獲得更多示例和更多關於此內容的解釋。 希望這篇文章有幫助! 🦀🦀

回答網友提問:雲科碩畢,上班中,考慮轉職軟體工程師,請問有建議嗎?

阿川收到網友提問如下: > 阿川你好: > 我的背景是雲科碩畢業,算是混上去的,現在打算轉職軟工,由於有在工作,所以打算先以自學為主3-6個月,看情況後決定是否報名資策會。 > 想請問一下,目前比較希望能夠走後端(網頁開發類),查了一些相關資訊,網頁似乎比較友善,未來有機會再往其他產業前進! > 搜尋了一下職務,網頁類的後端其實也需要html css js 前端三本柱。 > 我想問的是: > 1.是否直接開始學三本柱比較好?(反正前面的作品、入職也會需要)且 有了js基礎還能繼續學習node.js(後端)。 不過又礙於可能比較沒方向,會變成說學一學越來越往前端過去? > 2.先以門檻較低的前端入門、入職以後再好好思考想專精哪一端之類的 or 以c#為主學習,再慢慢學三本柱,資料庫等等 > 3.前端的切版技術等等,是否真的必要? 本人美感很差.. 兩個問題的考量的都是想說是否先以java,c#等後端去建立程式概念或許比較好。 > 文有點長,再麻煩您給我一些建議了,也想順便問一下,有看到您有提供免費html css 以及付費js課程,能在跟您要這方面的資訊嗎? 這些問題很好,我一樣公開回答,給類似狀況的人參考。 --- 簡單回答如下: 1、不論前後端 html 跟 css 都要會,所以這兩個可以先學。js 的話後端不用學精,稍微會寫就好,除非你是寫 node 至於最後會去前端或後端的職缺,都可以,先不用擔心這個,不然你就找全端的職缺也可以 2、後端需要學資料庫、基本伺服器管理,語言的話 C# 或 java 或 php 或 python 或 node 之類的都可以 3、前端做久了,因為常常跟設計師合作,會慢慢具備一點設計素養。如果對「UI 設計」有興趣是最好,沒有的話,倒也沒關係。美感可以慢慢訓練,先不用畫地自限 --- 總結來說,我建議你就先學 html 與 css,之後再看你用 html css 把網頁寫漂亮有沒有興趣,如果喜歡把畫面弄漂亮,就多學一點前端。如果只想做工程,就專心在後端吧。這些問題學了 html css 之後會更清楚,先不用太糾結。不然你就以全端為方向也可以,前後端都寫!你就先挑一個免費 or 便宜的線上課程,先開始寫寫看再說 先開始行動,會更清楚自己在做什麼,之後需要花大錢去報名補習班時,也會比較有把握 就算你一開始只寫前 or 後端,很多人上班之後,因為工作需求,還是慢慢有具備全端的技能 其實不用太排斥全端,都寫的話,一來在公司能做的事情變多、能應徵的機會變多,二來還可以自己用業餘時間寫 side project,因為一個人就能做完全部事情,所以會很好玩,也對職業生涯很有幫助 關於我設計的免費 html css 教材,請參考:https://codelove.tw/courses/frontend-beginner 另外,轉職過程會有諸多問題,可以加我們 LINE 群多跟大家討論:https://line.me/ti/g2/nipkjq2WoZPKX5dTn9tE9266aEOt6EOICFGa1g --- 以上,簡單分享,希望對大家有幫助!

非同步 JS 訓練二:第6課 ── 認識 async/await 語法與收尾處理

## 課程目標 - 認識 async/await 語法與收尾處理 ## 課程內容 接著來學 async/await 的收尾處理吧! 說起來也神奇,只要加上 `finally` 區塊就可以了! ``` try { const data1 = await $.get(url, params); // do something with data to get params2 const data2 = await $.get(url2, params2); // do something with data to get params3 const data3 = await $.get(url3, params3); // do the final task with data } catch (err) { alert('Something went wrong.'); } finally { // hide the loading icon } ``` 因為 `try/catch/finally` 本來就是一般同步程式設計語言會用到的錯誤處理語法 所以這整段程式碼,看起來跟一般的同步程式設計,幾乎一模一樣! 就是這麼奇妙!應該不用我多解釋什麼了! --- 多補充一句,我個人開發比較複雜的前端應用時,最常用的語法就是這種! 我認為 `async/await` 加上 `try/catch/finally` 是最簡潔有力的! 錯誤訊息提示、忙碌狀態提示,通通都有了,很輕易就做出 UX 很棒的應用程式! ## 課後作業 請拿出第三課的作業,我們來改善這個頁面的 UX(使用者體驗),明確提示「忙碌中」這個狀態 --- - 請用 html 元素,在頁面中加入一段 `讀取中,請稍等...` 的訊息,這個元素預設不顯示 - 在開始呼叫 API 的地方,用 js 操作來讓那個 html 元素顯示 - 在結束呼叫 API 的地方,使用 `finally` 語法,用 js 操作來讓那個 html 元素隱藏 做出以上功能,你就完成這次的課程目標了!

非同步 JS 訓練二:第5課 ── 認識 promise chain 鏈接與收尾處理

## 課程目標 - 認識 promise chain 鏈接與收尾處理 ## 課程內容 接著來學 promise chain 的收尾處理吧! 繼續拿 jquery 當範例,只要在上次的 promise chain 最後,加上 `.always()` 就可以了! ``` $.get(url, params).then((data) => { // do something with data to get params2 return $.get(url2, params2); }).then((data) => { // do something with data to get params3 return $.get(url3, params3); }).then((data) => { // do the final task with data }).catch((err) => { alert('Something went wrong.'); }).always(() => { // hide the loading icon }); ``` 很簡潔有力吧! ### ⚠️特別注意事項⚠️ 因為某些歷史因素,jquery 包裝的 promise 跟現在瀏覽器原生的 promise 有點不太一樣! 原生的 promise 是 `.finally()`,而不像 jquery 是 `.always()`! 為了教學方便,本課&作業都用 jquery 示範,實務上如果看到 `.finally()` 請不要意外! 都是類似東西,知道這樣就好! ## 課後作業 請拿出第二課的作業,我們來改善這個頁面的 UX(使用者體驗),明確提示「忙碌中」這個狀態 --- - 請用 html 元素,在頁面中加入一段 `讀取中,請稍等...` 的訊息,這個元素預設不顯示 - 在開始呼叫 API 的地方,用 js 操作來讓那個 html 元素顯示 - 在結束呼叫 API 的地方,使用 `always()`,用 js 操作來讓那個 html 元素隱藏 寫完之後,你應該會發現不但 callback hell 改善了、錯誤處理有了、連 UX 都改善了! 做出以上功能,你就完成這次的課程目標了!

非同步 JS 訓練二:第4課 ── 認識 callback hell 與收尾處理

## 課程目標 - 認識 callback hell 與收尾處理 ## 課程內容 研究完 callback hell、promise chain、async/await 的錯誤處理 接著來用三課的時間,分別研究收尾處理吧! 讓我們先從 callback hell 的寫法開始! --- 什麼是收尾處理? 其實就是,有些事情,不論任務執行成功 or 失敗,都固定要執行 這種事情,可以在 success callback 跟 error callback 最後都寫,但這樣就重複寫了,很煩! 所以就有所謂的收尾處理,讓你寫一次就好了 如果繼續拿 jquery 做範例,看起來會像這樣: ``` $.ajax({ url: url, data: params, success: (res) => {}, error: (res) => {}, complete: () => {}, }); ``` 其實,就是再多一個 callback function 而已!很單純吧! 在連續多個 ajax call 的時候,錯誤處理機制,再加上收尾處理機制,想想看 callback hell 會有多嚴重! --- 看到這邊,你可能會想,到底什麼事情需要在收尾機制處理呀? 其實,以我個人經驗來說,需要放進收尾處理的東西,其實很少 最常見的就是處理畫面上的「載入中,請稍等...」的文字,或者是畫面上「用來代表忙碌中的一個旋轉的圖示」 不論任務執行結果,都需要把這些文字、圖示隱藏 老實說,很多人根本連「忙碌中」這個狀態也沒做,導致 UX 不太好 所以實務上,如果你發現專案中不太會寫收尾處理,那也算正常,你就知道有這功能可以用即可 ## 課後作業 在第一課的作業,你已經體驗到了 callback hell 與錯誤處理的悲劇 忍耐一下,這一課要再體驗一下當年工程師的痛苦:加上收尾處理吧! 請拿出第一課的作業,我們來改善這個頁面的 UX(使用者體驗),明確提示「忙碌中」這個狀態 --- - 請用 html 元素,在頁面中加入一段 `讀取中,請稍等...` 的訊息,這個元素預設不顯示 - 在開始呼叫 API 的地方,用 js 操作來讓那個 html 元素顯示 - 在結束呼叫 API 的地方,使用 `$.ajax()` 的 `complete` 參數,用 js 操作來讓那個 html 元素隱藏 寫完之後,你應該會發現,有點難寫,而且顯示/隱藏的時機,有點奇怪! 如果想要讓顯示/隱藏的時機,完全正確,那就會重複很多一樣的 code! 別懷疑,就是這麼難寫、這麼奇怪!這就是當年前端開發的為難之處! 做出以上功能,你就完成這次的課程目標了!

CodeLove 前輩分享寫作計畫:VIP 審核限定

大家好,我是站長阿川 我留意到 LINE 群組的討論非常踴躍 很多迷惘、想轉職的新手,各種發問,都有業界工程師幫忙回答,非常熱心! 各位很多的回答「非常詳細」,完整到我覺得:只有群組內的新手看到,也太可惜! 應該讓網路上更多人都能看到,這樣更造福眾生、未來有人 google 搜尋也能夠找到! 繁體中文社群,需要知識不斷累積。如果一直在 FB 等等聊天室討論,然後被洗掉,有點可惜! 這也是我建立 CodeLove 網站的初衷!所以我設計了一個新計畫,跟大家分享一下! # CodeLove 前輩分享寫作計畫:VIP 審核限定 我鼓勵大家,在回答新手之餘,如果覺得 LINE 訊息文字篇幅不夠,或是 LINE 程式碼排版不易 請直接在 CodeLove 寫一篇完整文章,然後再貼到 LINE 群組內! 舉例來說,我自己就有這樣回答 LINE 群組新手的習慣: [轉職軟體工程師的方法很多,到底該如何選擇:實體補習班、線上補習班、不花錢自學?](https://codelove.tw/@howtomakeaturn/post/NxN2Kx) [回答網友提問:如果前端要銜接後端的話,是不是學 node.js 比較快?](https://codelove.tw/@howtomakeaturn/post/2anP0x) [回應網友提問:我是新手前端,公司叫我學一點 php + laravel 串 API,該從哪邊學起呢?](https://codelove.tw/@howtomakeaturn/post/Zq4Ona) # 如何成為這個計畫的 VIP? 原則上只接受「業界工程師」加入,也就是有工作經驗者加入! 就算只有一年工作經驗,也是正在轉職的新手的前輩,所以也歡迎! 越資深的話越好,因為您有大量的知識&經驗可以分享!真的是大前輩! **請在 CodeLove 網站上,任意發表一篇技術文章 or 工作心得,完成之後,點擊下方 LINE 群組加入:** https://line.me/ti/g2/9V19e5igoaUts-hrn1Vr3nNHMcGLLa1hJiaFRg 經過我審核之後,您就加入這個 VIP 群組了! (例外情況:您是學生,但明顯有極大分享熱情&知識,也會允許加入) # 身為這個群組的 VIP,可以幹嘛? 首先,我希望您寶貴的文章,能被儘量多的讀者看到! 您只要負責寫作就好,我會幫您「製造精美封面圖片」以及「行銷宣傳您的文章」! 凡是 VIP 前輩發文,我都會在有超過三百人的群組「愛寫扣論壇:發問&交流&討論群」轉貼,並且「設定為公告置頂至少24小時」! 再來,VIP 群組內都是「樂於分享、經驗豐富、寫作能力出色」的業界人士,大家可以在小群組內交流,我認為互相交換情報,也很有價值! 最後,如果我覺得您的文章實在應該被「成千上萬的更多讀者看到」,我會直接到各大論壇,到處轉貼宣傳您的文章,類似下面這樣: - https://www.dcard.tw/f/softwareengineer/p/252600314 - https://www.dcard.tw/f/f2e/p/252598230 - https://forum.gamer.com.tw/C.php?bsn=60076&snA=7835159 - https://forum.gamer.com.tw/C.php?bsn=60292&snA=8421 我會確保您的文章被數千、數萬人閱讀!身為寫作者,通常文章四處發表,會到處被不同工程師嘴砲、開嗆,沒關係,這很正常,我會擋在砲火最前面!您不用被這些負面訊息轟炸,我只會回報有意義的正面留言給您! 如果有很棒的留言或 feedback,我會貼回 VIP 群組內通知您! # 我想加入,但我沒什麼寫作靈感,怎麼辦? 首先,如果您有想發表的技術文章,當然可以直接當成寫技術部落格,寫一篇發表! 再來,您可以在 LINE 群組,看看新手們都在問些什麼,然後就當作在回答他們,直接公開寫一篇完整回答! 最後,也可以是您近期的一些技術筆記、工作隨筆,稍微整理之後發表,這種筆記也常常對後人很有價值! # 結論 我真的覺得繁體中文世界,需要有一個優質的討論區、寫作園區,知識才能有效累積,這個國家的軟體產業才能進步、發達 另外,這個 CodeLove 論壇是有 [文章 API](https://codelove.tw/@howtomakeaturn/post/jqeDka) 功能的 您可以在這邊大量寫作,之後呼叫 API 串接到自己的部落格,markdown 格式與 html 格式的轉換我都已經幫您做好了 以上,各位熱心的工程師,誠摯歡迎您加入「CodeLove 前輩分享寫作計畫」!一起造福眾生吧! https://line.me/ti/g2/9V19e5igoaUts-hrn1Vr3nNHMcGLLa1hJiaFRg 有問題歡迎直接留言與我討論!

【前端動手玩創意】動態生成的藝術|小心,亂改DOM你可能會被打臉。

## 目錄 ##### [【前端動手玩創意】等待的轉圈圈效果 (1)](https://ithelp.ithome.com.tw/articles/10311621) ##### [【前端動手玩創意】google五星評分的星星(2)](https://ithelp.ithome.com.tw/articles/10311643) ##### [【前端動手玩創意】CSS-3D卡片翻轉效果(3) (今天難度頗高,想挑戰再進來!)](https://ithelp.ithome.com.tw/articles/10311672) ##### [【前端動手玩創意】一句CSS做出好看的hero section!(4)](https://ithelp.ithome.com.tw/articles/10311691) ##### [【前端動手玩創意】創造一個Skill bar(5)](https://ithelp.ithome.com.tw/articles/10311756) ##### [【前端動手玩創意】遮蔽廣告(D卡未登入)腳本、自定義新增名單(6)](https://ithelp.ithome.com.tw/articles/10311999) ##### [【前端動手玩創意】前端canvas截圖的招式!竟然有三招,可存成SVG或PNG (7)](https://ithelp.ithome.com.tw/articles/10312001) ##### [【前端動手玩創意】讓你的PDF檔案更難被抓取(8)](https://ithelp.ithome.com.tw/articles/10312046) ##### [【前端動手玩創意】哇操!你敢信?花式寫todo-list,body裡面一行都沒有也能搞?(9)](https://ithelp.ithome.com.tw/articles/10312056) ##### [【前端動手玩創意】卡片製作,才不是!是卡片製作器!(10)](https://ithelp.ithome.com.tw/articles/10312066) ##### [【前端動手玩創意】太屌了吧!?用Class(類)製作Jquery的效果!(11)](https://ithelp.ithome.com.tw/articles/10312114) ##### [ 【前端動手玩創意】置頂按鈕,老梗經典|帶你的網頁搭電梯(12)](https://ithelp.ithome.com.tw/articles/10312922) ## 前情提要 一陣子沒寫前端動手玩創意了 今天要來點好料的 我們談談關於藝術 對 就算是寫程式我們也是可以有藝術氣息的 別這麼驚訝XD 假設我有一組資料 一般人來說 最直覺的就是把html裡面的元素寫出來寫死 直覺菜鳥就是寫出來啊 ``` <div id="items_list"> <li class="buy_item">1.紅茶 <div class="price">10</div> <div class="del_btn">X</div> </li> <li class="buy_item">2.奶茶 <div class="price">15</div> <div class="del_btn">X </div> </li> <li class="buy_item">3.綠茶 <div class="price">30</div> <div class="del_btn">X</div> </li> </div> ``` 要更新則是就去更改DOM就好了 反正我都學會JS了 有什麼大不了(? 但是現在已經進入大前端時代了就算你寫原生 也會有data model的概念 這部分可以參考站長阿川寫過的好文 裡面的文筆跟邏輯 不誇張 是我見過「華文圈寫得最好的前端教學」 尤其就是這篇 關於data model的介紹 切入點非常的有趣也很有道理 有興趣的自己去花心思讀看看 [認識 data model 與 render function](https://codelove.tw/@howtomakeaturn/post/9xLo5q) 稍微有點料的前端學習者 本身就會寫一寫 想說:既然有一隻API是createElement 那是不是我可以整個html都用js寫出來(? 這是個超級有趣的觀點 ## 關於data render的概念: 「是不是我可以整個html都用js寫出來」 相傳牛頓提出三大定律以後 認為地球和八大行星一開始的慣性力叫「上帝的第一推動力」 實際上這個: 「整個html都用js寫出來」 也是推動前端往框架邁進的思考第一步 可以說是前端慣性的上帝推力了 當然如果你有打籃球 也可以比喻成上籃的第零步XD ## 觀念筆記 ### html程式碼 ``` <div id="buylist"> <h1>myBuylist 購物清單</h1> <div class="buyitem"> <label>產品名</label> <input/> <label>價錢</label> <input/><span class="addbtn">+新增</span> </div> <div id="items_list">這邊準備用JS插入東西所以這段只是說明文字</div> </div> ``` 把整個頁面的元素寫出來 但是資料的區塊保留著 因為等等我們要用JS的API去動態生成 未來直接data render 方便更新與管理 ### JS程式碼 ``` var shoplist = {}; shoplist.name = "購物清單"; shoplist.list = [ { name: "吹風機", price: "300" }, { name: "麥克筆", price: "20" }, { name: "筆記型電腦", price: "29300" }, { name: "Iphone 9", price: "5200" }, { name: "神奇海螺", price: "1000" }, ]; var item_html = "<li id={{id}} class='buy_item'>{{name}}<div class='price'>{{price}}</div><div class='del_btn'>X</div></li>"; var total_html = "<li class='buy_item total'>總價<div class='price'>{{price}}</div><div class='del_btn'>X</div></li>"; var total_price = 0; for (var i=0; i < shoplist.list.length; i++) { var item = shoplist.list[i]; total_price += item.price; var current_item_html = item_html.replace("{{num}}", i + 1) .replace("{{name}}", item.name) .replace("{{id}}", "buyitem_" + i) .replace("{{price}}", item.price); $("#items_list").append(current_item_html); } ``` 這邊值得關注的一點是資料的處理 也就是數據結構上使用物件與陣列去儲存資料 為什麼要學 陣列 為什麼要學物件 這兩個都是抽象的名詞 他們都是為了來處理資料所規劃的兩種不同內容 ## 關於物件與陣列 物件就像是RPG角色 會有很多的屬性 魔法 敏捷 力量 血量 這些屬性都是被附加在person上面 所以person.blood是一個資料 person.power是一個資料 person.magic是一個資料 最後都存在person裡面 這個person就是一個含有很多屬性的物件 感覺就是有血有肉很3D 而陣列就比較平面化 就是很多數字排成一列而已 其實沒什麼特別需要關注的 這兩個也不會不好區分 只要稍微做個比喻 都很好理解 以我們的code來講解 shoplist就是一個物件 含有一些屬性 包含名字與清單 因為清單很多 所以清單用一個陣列儲存 陣列裡面放很多個物件 這些物件就是每一個清單包含的那些購買項目 其實不用太在意誰是誰因為用看的就很清楚 最後我們用迴圈去把shoplist裡面的每一筆資料都丟進去 中途replace是文字處理 把我們設置的{{name}}這種花括號的東西換成真實資料 這部分有點樣板語言的感覺XD 其實非常有趣 很值得玩味 ## 心得 這次比較多實在的JS程式碼 就不只是玩玩切版了 算是有點靠近框架的部分(◉3◉) 動手玩創意這個系列其實靈魂之處就在於「有趣」兩個字 坊間把前端描繪成為了找工作的銅臭味 以及把切版講成無聊的工匠苦力活 我認為都是錯誤的解讀 我認為 只要是有趣的地方就是前端最有價值的地方 而不是誰學了那個框架 誰又認為哪個東西比較厲害 哪個語言比較屌 那都是很無聊的文字遊戲罷了 如果你喜歡這樣子的前端 請跟著這個系列繼續走(→ܫ←) 我們才只是在桃花源外的小溪旁玩水而已呢! 未來會往天空飛翔哦XD