国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁 web前端 js教程 停止犯這些組件錯誤

停止犯這些組件錯誤

Nov 19, 2024 am 10:43 AM

Stop Making These Component Mistakes

事實是,組件看似簡單。上手很簡單——定義一個函數(shù),回傳一些 JSX,然後就到此為止。但是要編寫乾淨(jìng)、可維護且易於使用的元件嗎?這是一場完全不同的比賽。

在沒有意識到的情況下,我們建立了以下元件:

  • 太大了,一眼看不懂。
  • 測試起來非常困難。
  • 耦合如此緊密,無法重複使用。
  • 由於糟糕的績效決策而遲緩。

在這篇文章中,我將引導(dǎo)您了解開發(fā)人員在使用 React 元件時最常見的錯誤。更重要的是,我將向您展示如何在不破壞整個應(yīng)用程式的情況下修復(fù)它們。

無論您是剛?cè)腴T還是擁有多年的經(jīng)驗,這些技巧都將幫助您編寫出不僅具有功能性而且易於維護的組件。

“一切組件”反模式

讓我們來談?wù)勎覀兌挤高^的經(jīng)典錯誤:一切組件。您已經(jīng)看到它了——它一開始很小而且天真無邪,可能是一個簡單的表單或儀表板??燹D(zhuǎn)一點,現(xiàn)在它正在管理狀態(tài)、處理 API 呼叫、格式化數(shù)據(jù),還可能為您沖泡早晨咖啡。

// Please, no more of this
const UserDashboard = () => {
  const [userData, setUserData] = useState(null);
  const [orders, setOrders] = useState([]);
  const [notifications, setNotifications] = useState([]);
  const [settings, setSettings] = useState({});
  const [isEditing, setIsEditing] = useState(false);
  const [activeTab, setActiveTab] = useState('profile');

  // 15 separate useEffects
  // 10 different event handlers
  // Multiple conditional renders
  // 300+ lines of chaos
};

聽起來很熟悉嗎?

如何判斷你是否有罪

如果出現(xiàn)以下情況,您的組件可能已變成「一切組件」:

  • 狀態(tài)過載:您正在追蹤超過 3-4 個獨立的狀態(tài)。
  • 無休止的滾動:你花了太多時間尋找特定的功能或邏輯。
  • 依賴項膨脹: 你的 useEffect 依賴項看起來就像你的每週購物清單。
  • 否認(rèn)功能蔓延:你不斷告訴自己,多一個功能不會有什麼壞處。

分解它

解決方案?不要使用單一的所有組件,而是將職責(zé)分解為更小的、更有針對性的部分。

// A cleaner, smarter approach
const UserDashboard = () => {
  return (
    <div>
      <UserProfile />
      <OrderHistory />
      <NotificationCenter />
      <UserSettings />
    </div>
  );
};

關(guān)鍵原則:邏輯>佈局

重構(gòu)時,不要根據(jù)組件在螢?zāi)簧系耐庥^來破壞它們。按責(zé)任劃分他們。問問自己:這個功能是否值得擁有自己的組件?如果它正在處理一些不同的東西——例如用戶個人資料或訂單歷史記錄——它可能會這樣做。

提示: 一個好的組件只做一件事並且做得很好。如果您很難用一句話描述它的目的,那麼它很可能試圖做太多事情。

螺旋槳鑽井地獄

我們來討論一下不太好玩的「傳遞道具」遊戲。如果您曾經(jīng)將同一個 prop 透過多個元件傳遞給一個深度嵌套的子元件,那麼您就陷入了 prop 鑽探地獄。

// Please, no more of this
const UserDashboard = () => {
  const [userData, setUserData] = useState(null);
  const [orders, setOrders] = useState([]);
  const [notifications, setNotifications] = useState([]);
  const [settings, setSettings] = useState({});
  const [isEditing, setIsEditing] = useState(false);
  const [activeTab, setActiveTab] = useState('profile');

  // 15 separate useEffects
  // 10 different event handlers
  // Multiple conditional renders
  // 300+ lines of chaos
};

這種方法不僅令人煩惱,而且還會造成長期問題。想像一下需要重命名 user 屬性。突然,您在五個或更多地方更新它。更糟的是,您最終將組件與它們甚至不使用的資料綁定在一起。

如何解決這個問題

無需用道具來應(yīng)付燙手山芋。這裡有兩個實用的解決方案,可以完全避免鑽孔。

1。使用共享資料的上下文

如果跨應(yīng)用程式的不同部分存取一段數(shù)據(jù),React 的 Context API 可以簡化事情。

// A cleaner, smarter approach
const UserDashboard = () => {
  return (
    <div>
      <UserProfile />
      <OrderHistory />
      <NotificationCenter />
      <UserSettings />
    </div>
  );
};

2。使用組合來提高靈活性

不要通過層強制道具,而是重組組件,以便它們只傳遞需要的內(nèi)容。

// This is exhausting
const App = () => {
  const [user, setUser] = useState({});
  return (
    <Layout user={user}>
      <Sidebar user={user}>
        <Navigation user={user}>
          <UserMenu user={user} />
        </Navigation>
      </Sidebar>
    </Layout>
  );
};

重點

上下文非常適合應(yīng)用程式範(fàn)圍的數(shù)據(jù),例如使用者資訊、主題或全域設(shè)定。然而,它並不總是最好的選擇——不要過度使用它。對於局部狀態(tài),考慮是否可以調(diào)整組件結(jié)構(gòu)以避免完全鑽取。

目標(biāo)是讓你的元件清晰且可維護。避免螺旋鑽探將為您節(jié)省時間、減少挫敗感並避免日後無數(shù)令人頭痛的問題。

過早的優(yōu)化陷阱

您可能聽過關(guān)於過早優(yōu)化是萬惡之源的名言。好吧,歡迎來到組件級邪惡。我說的是那些時候,我們甚至不知道是否需要兩次之前就嘗試讓所有東西都可重複使用。

通常是這樣的:

const UserContext = createContext();

const App = () => {
  const [user, setUser] = useState({});
  return (
    <UserContext.Provider value={user}>
      <Layout>
        <Sidebar>
          <Navigation />
        </Sidebar>
      </Layout>
    </UserContext.Provider>
  );
};

// Use it only where needed
const UserMenu = () => {
  const user = useContext(UserContext);
  return <div>{user.name}</div>;
};

讓你的組件自然發(fā)展。為您知道您今天需要的東西而建造。如果出現(xiàn)新的需求,請在可以清楚證明其合理性的情況下添加功能。過早的優(yōu)化會浪費時間,增加複雜性,而且很少有回報。

記?。?/strong> YAGNI 原則(你不會需要它)也適用於組件。當(dāng)你真正遇到了他們正在解決的問題時,最好的抽象就會出現(xiàn)。過度設(shè)計可能會讓人覺得很主動,但簡單總是勝出。

副作用管理不善

這是一個不良效果管理的經(jīng)典例子??雌饋砗苎凼靻幔?

// Focused components for better clarity
const Navigation = ({ children }) => {
  return <nav>{children}</nav>;
};

// Pass data only where required
const App = () => {
  const user = useUser();
  return (
    <Layout>
      <Navigation>
        <UserMenu user={user} />
      </Navigation>
    </Layout>
  );
};

常見錯誤和修復(fù)

1) 混亂的資料取得

糟糕的資料處理產(chǎn)生的錯誤比它解決的錯誤還要多。這是一種更簡潔的方法:

// Behold, the over-engineered button
const Button = ({ 
  children,
  variant = 'primary',
  size = 'medium',
  isFullWidth = false,
  isDisabled = false,
  isLoading = false,
  leftIcon,
  rightIcon,
  onClick,
  customClassName,
  style,
  loadingText = 'Loading...',
  tooltipText,
  animationType,
  // ... 10 more props
}) => {
  // 50 lines of prop processing logic
  return (
    <button 
      className={generateComplexClassNames()}
     >



<h3>
  
  
  Why This Hurts
</h3>

<ul>
<li>Your “simple” button now requires an instruction manual.</li>
<li>Most of those 15+ props will never be used.</li>
<li>Making updates becomes risky because you have to account for endless combinations.</li>
<li>Writing tests becomes painful, with a hundred possible scenarios to consider.</li>
</ul>

<h3>
  
  
  Better Approach:
</h3>

<p>Instead of building for every imaginable scenario, start small and let your components grow as needed.<br>
</p>

<pre class="brush:php;toolbar:false">// Start simple
const Button = ({ children, onClick, variant = 'primary' }) => {
  return (
    <button 
      className={`btn btn-${variant}`}
      onClick={onClick}
    >
      {children}
    </button>
  );
}

// Create specific buttons when you actually need them
const LoadingButton = ({ isLoading, children, ...props }) => {
  return (
    <Button {...props}>
      {isLoading ? 'Loading...' : children}
    </Button>
  );
}

2) 忘記清理

總是清理乾淨(jìng)自己:

const UserProfile = ({ userId }) => {  
  const [user, setUser] = useState(null);  
  const [posts, setPosts] = useState([]);  

  // Dependency array woes
  useEffect(() => {  
    fetchUserData(userId);  
    fetchUserPosts(userId);  
    // No cleanup? Yikes.
  }, []); // eslint-disable-line react-hooks/exhaustive-deps  

  // Multiple effects, all tangled
  useEffect(() => {  
    const subscription = subscribeToUserStatus(userId);  
  }, [userId]);  

  // Cleanup? What cleanup?
  useEffect(() => {  
    const interval = setInterval(checkNotifications, 5000);  
  }, []);  
};

3) 忽略競爭條件

使用此技術(shù)避免重疊請求:

// Improved version
const UserProfile = ({ userId }) => {  
  const { data: user, isLoading } = useQuery(  
    ['user', userId],  
    () => fetchUserData(userId)  
  );  

  // Keep concerns separate
  const { data: posts } = useQuery(  
    ['posts', userId],  
    () => fetchUserPosts(userId),  
    { enabled: !!user }  
  );  
};

快速提示

  • 使用 useEffect 之前請三思:有時候,你可能根本不需要它。
  • 保持專注:一種效果應(yīng)該承擔(dān)一種責(zé)任。
  • 始終清理:訂閱、間隔和事件監(jiān)聽器需要注意。
  • 使用正確的工具:像 React Query 這樣的函式庫可以簡化資料取得和快取。
  • 不要用 eslint-disable 作弊:修復(fù)依賴問題而不是隱藏它們。

性能盲點

讓我們來談?wù)勀切┩低得男軉栴}。他們是那種在雷達(dá)下飛行的人,因為一切看起來都很好——直到事實並非如此。讓我們揭開這些無聲的罪魁禍?zhǔn)?,看看如何解決它們。

問題

這是一個存在一些微妙性能缺陷的組件:

// Please, no more of this
const UserDashboard = () => {
  const [userData, setUserData] = useState(null);
  const [orders, setOrders] = useState([]);
  const [notifications, setNotifications] = useState([]);
  const [settings, setSettings] = useState({});
  const [isEditing, setIsEditing] = useState(false);
  const [activeTab, setActiveTab] = useState('profile');

  // 15 separate useEffects
  // 10 different event handlers
  // Multiple conditional renders
  // 300+ lines of chaos
};

你能發(fā)現(xiàn)問題嗎?讓我們把它們分解一下。

修補

1) 記住昂貴的計算

不要在每次渲染時重新計算所有內(nèi)容,而是使用 useMemo 來快取結(jié)果:

// A cleaner, smarter approach
const UserDashboard = () => {
  return (
    <div>
      <UserProfile />
      <OrderHistory />
      <NotificationCenter />
      <UserSettings />
    </div>
  );
};

這避免了在每次渲染時重新計算資料並重新建立事件處理程序。它還可以防止帶有備忘錄的子元件不必要的重新渲染。

2) 高效率的狀態(tài)更新

糟糕的狀態(tài)管理也會降低效能。這是處理搜尋結(jié)果等更新的更好方法:

// This is exhausting
const App = () => {
  const [user, setUser] = useState({});
  return (
    <Layout user={user}>
      <Sidebar user={user}>
        <Navigation user={user}>
          <UserMenu user={user} />
        </Navigation>
      </Sidebar>
    </Layout>
  );
};

去抖動確保我們不會在每次按鍵時獲取數(shù)據(jù),從而減少不必要的 API 呼叫和重新渲染。

快速效能提示

  • 不要過度使用記憶:僅在值得的時候進行最佳化。
  • 避免內(nèi)嵌函數(shù):穩(wěn)定的引用可以提高效能。
  • 保持 props 可預(yù)測:淺且穩(wěn)定的 props 有助於組件保持高效。
  • 分解大型清單:像react-window這樣的工具可以優(yōu)雅地處理大資料集。
  • 將狀態(tài)移得更近:僅在實際需要的地方管理狀態(tài)。
  • 使用 DevTools 進行分析:最佳化前始終進行測量。

結(jié)論

建構(gòu)元件並不是什麼複雜的事情,但說實話,我們很容易養(yǎng)成壞習(xí)慣。我犯過這些錯誤中的每一個(有時仍然會犯)。沒關(guān)係。重要的是儘早發(fā)現(xiàn)它們、修復(fù)它們並避免粗糙的程式碼庫。

更好組件的快速清單

? 單一職責(zé):如果您無法用一句話概括組件的工作,那麼就該將其分解。

? 道具管理:層層傳遞道具?考慮使用上下文或利用組合來代替。

? 狀態(tài)與效果:集中效果,正確清理它們,並讓現(xiàn)代工具處理複雜的資料擷取。

? 效能:不要為了最佳化而最佳化-首先要衡量。在需要時巧妙地使用 memo、useMemo 和 useCallback 等工具。

? 從簡單開始:解決你現(xiàn)在遇到的問題,而不是將來可能遇到的問題。

最好的組件不是華而不實或過於聰明 - 它們是您的團隊可以在六個月內(nèi)閱讀和維護的組件。

記?。?/strong>這些不是硬性規(guī)則,只是指導(dǎo)方針。有時你會打破它們,那很好。我們的目標(biāo)不是完美,而是建立一些組件,讓您在以後重新審視自己的職業(yè)選擇時不會產(chǎn)生疑問。

以上是停止犯這些組件錯誤的詳細(xì)內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

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

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Java vs. JavaScript:清除混亂 Java vs. JavaScript:清除混亂 Jun 20, 2025 am 12:27 AM

Java和JavaScript是不同的編程語言,各自適用於不同的應(yīng)用場景。 Java用於大型企業(yè)和移動應(yīng)用開發(fā),而JavaScript主要用於網(wǎng)頁開發(fā)。

JavaScript評論:簡短說明 JavaScript評論:簡短說明 Jun 19, 2025 am 12:40 AM

JavascriptconcommentsenceenceEncorenceEnterential gransimenting,reading and guidingCodeeXecution.1)單inecommentsareusedforquickexplanations.2)多l(xiāng)inecommentsexplaincomplexlogicorprovideDocumentation.3)

如何在JS中與日期和時間合作? 如何在JS中與日期和時間合作? Jul 01, 2025 am 01:27 AM

JavaScript中的日期和時間處理需注意以下幾點:1.創(chuàng)建Date對像有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設(shè)置時間信息可用get和set方法,注意月份從0開始;3.手動格式化日期需拼接字符串,也可使用第三方庫;4.處理時區(qū)問題建議使用支持時區(qū)的庫,如Luxon。掌握這些要點能有效避免常見錯誤。

為什麼要將標(biāo)籤放在的底部? 為什麼要將標(biāo)籤放在的底部? Jul 02, 2025 am 01:22 AM

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

JavaScript與Java:開發(fā)人員的全面比較 JavaScript與Java:開發(fā)人員的全面比較 Jun 20, 2025 am 12:21 AM

JavaScriptIspreferredforredforwebdevelverment,而Javaisbetterforlarge-ScalebackendsystystemsandSandAndRoidApps.1)JavascriptexcelcelsincreatingInteractiveWebexperienceswebexperienceswithitswithitsdynamicnnamicnnamicnnamicnnamicnemicnemicnemicnemicnemicnemicnemicnemicnddommanipulation.2)

JavaScript:探索用於高效編碼的數(shù)據(jù)類型 JavaScript:探索用於高效編碼的數(shù)據(jù)類型 Jun 20, 2025 am 12:46 AM

javascripthassevenfundaMentalDatatypes:數(shù)字,弦,布爾值,未定義,null,object和symbol.1)numberSeadUble-eaduble-ecisionFormat,forwidevaluerangesbutbecautious.2)

什麼是在DOM中冒泡和捕獲的事件? 什麼是在DOM中冒泡和捕獲的事件? Jul 02, 2025 am 01:19 AM

事件捕獲和冒泡是DOM中事件傳播的兩個階段,捕獲是從頂層向下到目標(biāo)元素,冒泡是從目標(biāo)元素向上傳播到頂層。 1.事件捕獲通過addEventListener的useCapture參數(shù)設(shè)為true實現(xiàn);2.事件冒泡是默認(rèn)行為,useCapture設(shè)為false或省略;3.可使用event.stopPropagation()阻止事件傳播;4.冒泡支持事件委託,提高動態(tài)內(nèi)容處理效率;5.捕獲可用於提前攔截事件,如日誌記錄或錯誤處理。了解這兩個階段有助於精確控制JavaScript響應(yīng)用戶操作的時機和方式。

Java和JavaScript有什麼區(qū)別? Java和JavaScript有什麼區(qū)別? Jun 17, 2025 am 09:17 AM

Java和JavaScript是不同的編程語言。 1.Java是靜態(tài)類型、編譯型語言,適用於企業(yè)應(yīng)用和大型系統(tǒng)。 2.JavaScript是動態(tài)類型、解釋型語言,主要用於網(wǎng)頁交互和前端開發(fā)。

See all articles