我開發 React 應用程式已經有幾年了,我經歷了無數的錯誤,這些錯誤減慢了專案的開發速度。
React 是建立動態使用者介面的最受歡迎的程式庫之一,但它的靈活性也會導致新開發人員犯下某些常見錯誤。
本指南涵蓋了開發人員在 React 中最容易犯的錯誤,並提供了可操作的技巧來編寫更好、更有效率的程式碼。
讓我們開始吧!
1. 變異狀態
在繼續之前,讓我們先編寫我們的 React 元件,該元件應該顯示項目列表,以及新增或刪除一個項目:
import { useState } from "react"; const Home = (props) => { const [items, setItems] = useState(['item1', 'item2']); const [itemToAdd, setItemToAdd] = useState(''); function wrongHandleAddItem(item) { items.push(item); setItems(items); } function goodHandleAddItem(item) { if (item.length === 0) return; const newArray = [...items, item]; setItems(newArray); setItemToAdd(''); } function removeItem(item) { const itemIndex = items.indexOf(item); if (itemIndex !== -1) { const newArray = [...items]; newArray.splice(itemIndex, 1); setItems(newArray); } } return ( <div> <p>Here, I wrote two different methods to add an item in the items state array. Let's break it down together:<br> </p> <pre class="brush:php;toolbar:false">function wrongHandleAddItem(item) { items.push(item); setItems(items); }
此方法所做的第一件事是呼叫推送數組函數,旨在將元素添加到數組中。
第二件事是呼叫 setItems 將變更套用到狀態變數。
但是,如果您嘗試執行此程式碼,它將無法運作❌
這段程式碼違反了一個非常重要的 React 規則:改變狀態。
React 依靠狀態變數的身份來判斷狀態何時會改變。當我們將項目推入數組時,我們並沒有更改該數組的標識,因此 React 無法判斷該值已更改並重新渲染該數組。
以下是修復方法 ✅ :
function goodHandleAddItem(item) { if (item.length === 0) return; const newArray = [...items, item]; setItems(newArray); setItemToAdd(''); }
在此方法中,我使用展開運算子建立了一個新陣列...允許使用專案內容實例化新陣列。第二個參數用於新增內容(此處為 item)。
最後一步是呼叫 setItems 方法來驗證變數項目的新狀態 ✅
2. 不產生清單中的鍵
每個 React 開發者在他們的開發過程中可能至少見過一次這個錯誤。
發生這種情況的最常見方式是映射資料時。以下是此違規行為的範例:
items.map((item) => ( <div> {item} <button onclick="{()"> removeItem(item)}>-</button> </div> ))}
當我們想要渲染一個元素陣列時,我們需要為 React 提供更多的上下文以允許它識別每個項目。在最好的情況下,它必須是唯一識別碼。
這是解決此問題的快速方法,但這並不是最佳方法:
items.map((item, index) => ( <div key="{index}"> {item} <button onclick="{()"> removeItem(item)}>-</button> </div> ))}
當您獲得 React 經驗並了解它如何更好地工作時,您將能夠根據您的情況判斷它是否可以。
為了使其完美,您可以使用 uuid 產生器,例如 crypto.randomUUID() 並將其作為物件儲存到項目清單中,如下所示:
const newItemToAdd = { id: crypto.randomUUID(), value: item }; const newArray = [...items, newItemToAdd]; setItems(newItems);
並在渲染過程中如下使用它:
items.map((item, index) => ( <div key="{item.id}"> {item.value} <button onclick="{()"> removeItem(item)}>-</button> </div> ))}
現在一切都很完美✅
3.在useEffect中使用async
假設我們有一個函數需要在掛載時從 API 取得一些資料。我們將使用 useEffect 鉤子,並且我們想要使用 wait 關鍵字。
讓我們檢查一下第一次嘗試:
如您所知,await 關鍵字需要位於標有 async 關鍵字的函數中:
import { useState } from "react"; const Home = (props) => { const [items, setItems] = useState(['item1', 'item2']); const [itemToAdd, setItemToAdd] = useState(''); function wrongHandleAddItem(item) { items.push(item); setItems(items); } function goodHandleAddItem(item) { if (item.length === 0) return; const newArray = [...items, item]; setItems(newArray); setItemToAdd(''); } function removeItem(item) { const itemIndex = items.indexOf(item); if (itemIndex !== -1) { const newArray = [...items]; newArray.splice(itemIndex, 1); setItems(newArray); } } return ( <div> <p>Here, I wrote two different methods to add an item in the items state array. Let's break it down together:<br> </p> <pre class="brush:php;toolbar:false">function wrongHandleAddItem(item) { items.push(item); setItems(items); }
不幸的是,這不起作用,我們收到此錯誤訊息:
function goodHandleAddItem(item) { if (item.length === 0) return; const newArray = [...items, item]; setItems(newArray); setItemToAdd(''); }
這裡是修復:在 useEffect 掛鉤中建立一個單獨的非同步函數 ✅
items.map((item) => ( <div> {item} <button onclick="{()"> removeItem(item)}>-</button> </div> ))}
了解 async 關鍵字的意思很重要:
它不回傳物件 json,它傳回一個解析物件 json 的 Promise。
這實際上是一個問題,因為 useEffect 不應該返回 Promise。它期望我們要么不返回任何內容(就像上面的那樣),要么返回一個清理函數。清理功能很重要,超出了本指南的範圍,但這裡可以使用它:
items.map((item, index) => ( <div key="{index}"> {item} <button onclick="{()"> removeItem(item)}>-</button> </div> ))}
4. 重新渲染前訪問狀態
讓我們回到狀態管理,看看新開發人員常犯的另一個有趣的錯誤。這將幫助我們更好地理解 React 狀態。
讓我們用 goodHandleAddItem 方法來說明這一點:
const newItemToAdd = { id: crypto.randomUUID(), value: item }; const newArray = [...items, newItemToAdd]; setItems(newItems);
執行此程式碼時,我們可以看到控制台沒有記錄我們期望的結果。
問題是:狀態變數的setter 函數是非同步。
當我們呼叫 setItems 方法時,我們實際上是在安排更新,而不是分配變數。
這裡是修復:我們已經知道 newArray 變數的變數內容應該是什麼。這意味著要使用我們想要作為 items 變數內容的數據,即使在 setItems ✅ 之後,我們也需要 使用變數 newArray
來代替5. 使用陳舊的狀態數據
最後一篇也是關於React狀態管理的,看完這篇指南你就會成為專家了! ?
使用 React Hooks 時的一個常見陷阱是濫用過時的狀態資料。當我們在連續狀態更新中直接引用狀態變數時,可能會發生這種情況。正如我們在上一個錯誤中看到的,狀態更新可能是非同步的,這意味著狀態變數在連續呼叫中引用時可能不會反映最新值。
讓我們用一個全新的例子來讓事情變得更清楚,眾所周知的計數器:
items.map((item, index) => ( <div key="{item.id}"> {item.value} <button onclick="{()"> removeItem(item)}>-</button> </div> ))}
以上用法是錯誤的。事實上,count 是在 setCount 呼叫中直接引用的。在事件處理程序和生命週期方法中,狀態更新可以批量進行,並且都使用與計數相同的初始值,這將導致最終狀態不正確。
我們可以使用另一種形式的 setCount 來讓事情正常運作:更新函數。 updater 函數將先前的狀態作為參數並傳回新的狀態,因此每次連續的更新都會具有正確的值,從而防止出現不必要的行為。
使用方法如下:
import { useState } from "react"; const Home = (props) => { const [items, setItems] = useState(['item1', 'item2']); const [itemToAdd, setItemToAdd] = useState(''); function wrongHandleAddItem(item) { items.push(item); setItems(items); } function goodHandleAddItem(item) { if (item.length === 0) return; const newArray = [...items, item]; setItems(newArray); setItemToAdd(''); } function removeItem(item) { const itemIndex = items.indexOf(item); if (itemIndex !== -1) { const newArray = [...items]; newArray.splice(itemIndex, 1); setItems(newArray); } } return ( <div> <p>Here, I wrote two different methods to add an item in the items state array. Let's break it down together:<br> </p> <pre class="brush:php;toolbar:false">function wrongHandleAddItem(item) { items.push(item); setItems(items); }
記錄計數內容現在指示正確的值✅
結論
避免這些常見錯誤將使您開發出更高效能的 React 應用程式並掌握狀態管理!
希望這份指南對您有幫助,並祝您編碼愉快!
作為新的或已確認的 React 開發人員,如果您喜歡本指南,請留下一個讚?
很快再見!
以上是React 開發中最常見的錯誤以及如何避免它們 ⚛️的詳細內容。更多資訊請關注PHP中文網其他相關文章!

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

禪工作室 13.0.1
強大的PHP整合開發環境

記事本++7.3.1
好用且免費的程式碼編輯器

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

WebStorm Mac版
好用的JavaScript開發工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),