類別元件 vs 函式元件:深入比較與實際應用


摘要

本文深入比較了 React 中的類別元件與函式元件,幫助開發者理解它們各自的優缺點及實際應用情境。 歸納要點:

  • 類別元件在複雜狀態管理和生命週期事件上仍具優勢,但函式元件因引入 Hooks 而逐漸成為主流。
  • 函式元件效能通常更佳,特別是在大型應用中,而類別元件的 `shouldComponentUpdate()` 方法則可有效控制渲染次數。
  • 函式元件程式碼結構簡潔易讀,Hooks 的使用讓功能更豐富;相比之下,類別元件需掌握 `this` 指向及其他概念。
選擇適合的元件形式將對您的 React 開發效率和維護性產生深遠影響。

React 元件:可重用性、靈活性與效能最佳化

React 元件是獨立且可重用的程式碼區塊,廣泛應用於建立網頁應用程式的使用者介面。這些單元作為任何 React 應用程式的骨幹,讓開發者能夠將使用者介面拆分成子元件樹,每個元件管理其內容和行為。在核心部分,一個 React 應用程式的元件可以以兩種不同風格定義:類別元件和函式元件。類別元件在複雜狀態邏輯和生命週期管理方面較為傳統。它們提供了一種更結構化的方法來建立需要詳細生命週期方法和狀態管理的元件例項。

另一方面,函式元件則是使用 JavaScript 函式定義,適用於那些不需要大量管理狀態或生命週期方法的簡單應用程式。新興的 Hooks 機制使得在函式元件中管理狀態和生命週期變得更加便利,它簡化了複雜的狀態與生命週期管理,使得函式元件能擁有與類別元件相似的功能,同時更易於使用。

在最佳實踐及效能考量方面,React 持續進行最佳化並提供有效的方法以提升效能。例如,可以運用備註工具,例如 React Profiler 和 React Developer Tools,以識別效能瓶頸;同時善用 React Suspense 和 React.lazy 等技術,有效地管理元件載入與效能問題。

我們在研究許多文章後,彙整重點如下
網路文章觀點與我們總結
  • React 元件可分為函式元件(Functional)和類別元件(Class-based)。
  • 函式元件較簡潔,樣板程式碼少,易於理解與使用。
  • 類別元件符合物件導向設計,適用於需要複雜邏輯的情況。
  • 在 React 中,每個元件都是小而可重複使用的程式碼單位。
  • 從 React 16.8 開始,函式元件可以使用 Hook,增強其功能性。
  • 不同的元件之間可以互相傳遞資料,有助於組織與管理應用程式的狀態。

在學習 React 的過程中,我們會接觸到兩種建立元件的方法:函式和類別。對初學者來說,函式元件因其簡潔明瞭而受到青睞,而類別元件則提供了更豐富的物件導向特性。隨著 React 的演進,即使是簡單的功能也可以透過 Hooks 加入更強大的能力。無論選擇哪種方式,都能讓我們創建出靈活且可重複使用的介面元素,使得開發變得更加高效有趣!


React Hooks:賦予函式元件更強大功能

最初, React 元件主要是作為基於類別的實體來建立,需要定義一個擴充套件版本的 React.Component 類。這種設定使開發者可以使用生命週期方法,例如在元件掛載到 DOM 時進行操作,從而控制其生命週期。這些類別元件主要管理元件樹的結構。隨著 React 的演進,引入了 Hooks,使得函式元件也能夠管理狀態和副作用,這些功能起初僅限於類別元件。這一轉變意味著開發者可以編寫更簡潔的程式碼,同時減少 JavaScript 類別語法的負擔。

舉例來說,一個使用 Hooks 的函式元件可能看起來像這樣:

```javascript
import React, { useState } from ′react′;

function Example() {
const [count, setCount] = useState(0);

return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);

```

**專案1:Hooks的彈性與可重用性**
Hooks 的匯入提供了極佳的彈性與可重用性,允許開發者在不使用類別繼承的情況下加入狀態和行為。這簡化了元件的開發過程,使其易於維護和測試。開發者可以根據特定需求混合搭配各種 Hooks,從而建立符合特定邏輯和行為的元件。

**專案2:效能優勢**
與類別元件相比,使用 Hooks 的函式元件在效能上具有優勢。Hooks 允許在函式元件中使用狀態和副作用控制,而無需建立類別元件。這消除了類別元件中與建立和維護內部狀態相關的額外開銷,從而導致更快的渲染時間和更流暢的效能。

import React, { useState, useEffect } from 'react';  function UserProfile() {   const [user, setUser] = useState(null);    useEffect(() => {     fetchUserData().then(data => setUser(data));   }, []);    return (     
{user ? `Welcome, ${user.name}` : 'Loading...'}
); }

Class 和函式元件:React 開發中的優缺點比較

這段文字展示瞭如何使用 `useState` 和 `useEffect` 這兩個 Hook,以函式方式來處理狀態和生命週期特徵,與傳統的 class 方法形成對比。此發展突顯了一個重要趨勢,即 React 社群逐漸偏好於簡潔且高效的函式元件,尤其是在全面支援 Hooks 引入後。

在 React 中,class 元件因其結構化和靈活性而更適合管理應用程式中的複雜功能。它們繼承自 `React.Component`,使開發者能夠處理複雜的狀態邏輯及生命週期方法。我們接下來將探討這些元件是如何構建以及它們在日常中的應用案例。

**Class 元件語法**

Class 元件是使用 ES6 類別語法定義的。典型的 class 元件擴充套件自 `React.Component` 並包含一個渲染 (render) 方法,該方法返回一個 React 元素。這種結構對於建立元件樹至關重要,使得元件可以按照層級進行有序組織。

1. **複合元件的優勢**
傳統的 class 元件在處理複雜狀態邏輯和生命週期方法時具備較高的靈活性。它們可以定義多個生命週期方法,例如 `componentDidMount` 和 `componentWillUnmount`,針對特定使用案例進行最佳化。它們還可透過定義自己的狀態和方法來建立更複雜的互動與行為。

2. **函式元件與效能優勢**
儘管 class 元件提供更豐富的功能,但函式元件在效能和易用性上則具有明顯優勢。藉由使用函式元件和 Hooks,開發者可以以簡潔方式處理狀態及生命週期功能,而無需撰寫過多樣板程式碼。這不僅簡化了維護工作,也提高了重用性,尤其是在需要頻繁更新狀態或生命週期事件時,更能彰顯其便捷之處。

基本類別元件示例

import React, { Component } from 'react';  class App extends Component {   render() {     return 

Hello, welcome to the app!

; } } export default App;

在這個範例中,App 類別擴充套件了 Component,並封裝了其 render 方法。結尾的 export default App 語句使得 App 元件可以在應用程式的其他部分中使用。這是一個進階的類別元件,具有狀態管理功能。

class ClassComponent extends Component {   constructor(props) {     super(props);     this.state = {       data: null,     };   }    componentDidMount() {     this.fetchData();   }    fetchData = () => {     // Fetch data from an API and update state   }    render() {     return 
Data: {this.state.data}
; } } export default ClassComponent;

Class元件與函式元件在React應用程式中的比較

這個進階範例展示了一個管理自身狀態的 Class 元件,並包含了像是 componentDidMount 的生命週期方法來處理資料獲取等操作。Class 元件在 React 應用程式中扮演著至關重要的角色,特別是在需要複雜元件階層和狀態管理的情境下。它們的語法提供了一種清晰的模式來定義行為和渲染使用者介面,讓它們特別適合於更複雜的場景。

另一方面,函式元件則被定義為 JavaScript 函式,提供了一種更加簡潔明瞭的方法來撰寫元件,而不需要 Class 語法所帶來的額外負擔。隨著 Hooks 的引入,函式元件現在也可以管理狀態和生命週期功能,而這些在傳統上僅限於 Class 元件之中。

**專案1:深入探討 Class 元件的優點和限制**
Class 元件在 React 應用程式中扮演至關重要的角色,特別是在需要複雜的元件階層和狀態管理時。相較於函式元件,它們有其優缺點。因此,深入探討 Class 元件的優勢與限制,有助於我們了解何時最適合使用它們。

**專案2:涵蓋函式元件的演變與新特性**
隨著 React 的發展,函式元件在功能及應用上也持續演變。除了傳統上的簡潔與無狀態特性外,如今透過匯入 Hook 機制,它們能夠同樣地管理狀態與生命週期功能。了解函式元件如何演變以及新特性的加入,可以幫助開發人員評估其在不同場景中的適當性,以便做出明智的選擇。

在 Functional Components 中,我們可以看到其簡單直接——接受 props 並返回 React 元素。以下是一個基本示例:

簡單功能性元件的範例

import React from 'react';  function UserProfile({ user }) {   return 
Welcome, {user.name}!
; } export default UserProfile;

這段程式碼展示了一個功能性元件,接收使用者資料作為屬性並直接渲染它。功能性元件與 Hooks 的結合使得無需使用類別也能夠使用狀態及其他 React 功能。例如, useState 和 useEffect 讓功能性元件可以處理複雜的邏輯和副作用。以下是使用 useState 和 useEffect 的範例。

import React, { useState, useEffect } from 'react';  function Weather({ location }) {   const [weather, setWeather] = useState(null);    useEffect(() => {     fetchWeather(location).then(data => setWeather(data));   }, [location]);    return (     
{weather ? `Current temperature: ${weather.temp}°C` : 'Loading weather...'}
); } export default Weather;

在這個例子中,useState 負責管理天氣狀態,而 useEffect 則執行根據提供的位置獲取天氣資料的副作用。功能性元件,特別是搭配 hooks 的使用,非常適合現代 React 應用中的大多陣列件。它們簡化了反應式使用者介面的建立,減少了樣板程式碼的量,並使維護和測試變得更加容易。


在 React 中管理狀態和生命週期事件對於類元件和函式元件至關重要。本節將探討這兩種型別的元件如何處理這些方面,這對於構建能夠與使用者行為和資料動態互動的複雜元件而言,是不可或缺的。


class UserGreeting extends React.Component {   constructor(props) {     super(props);     this.state = { greeted: false };   }    componentDidMount() {     this.setState({ greeted: true });   }    render() {     return 

{this.state.greeted ? 'Hello, user!' : 'Welcome'}

; } }

function UserGreeting() {   const [greeted, setGreeted] = useState(false);    useEffect(() => {     setGreeted(true);   }, []);    return 

{greeted ? 'Hello, user!' : 'Welcome'}

; }

最佳化 React 元件效能:功能性元件與自訂 Hook 的威力

因此,雖然類別元件和功能性元件都能管理狀態和生命週期事件,但轉向使用帶有 Hooks 的功能性元件提供了一種更簡潔且不冗長的方法,促進了更輕鬆的維護以及在許多情況下更佳的效能。隨著應用程式規模擴大及複雜度增加,最佳化 React 元件的效能變得至關重要。本節探討有效管理狀態、最佳化渲染及提升類別與功能性元件整體效能的技術。

類別元件通常使用 this.state 來管理本地狀態,並透過 this.setState 進行更新。相對而言,功能性元件則利用 useState Hook,它提供了一種更加直接且易於理解的狀態管理方法。

**專案 1:自訂 Hook 的強大活用** 隨著 React 生態系的發展,自訂 Hook 已成為提升功能性元件效能的利器。它們允許開發人員封裝重複邏輯和狀態管理,使程式碼可以被重複使用且便於維護。例如,自訂 Hook 可用於管理複雜的表單狀態或與外部資料庫互動,從而簡化功能性元件的開發和維護。

**專案 2:備忘處理(Memoization)** 備忘處理是一種最佳化技術,用以防止不必要的元件重新渲染。在功能性元件中,可以利用 React 的 useMemo hook 對函式或計算值結果進行備忘,以避免每次重新渲染時都執行這些運算。這對於處理昂貴計算或資料轉換特別有用,可顯著提高元件效能和使用者體驗

 Copy code class LocalStateComponent extends React.Component {   constructor(props) {     super(props);     this.state = { count: 0 };   }    increment = () => {     this.setState(prevState => ({ count: prevState.count + 1 }));   };    render() {     return (       

{this.state.count}

); } }

函式式元件範例}

在 React 中,函式式元件是一種用來定義 UI 的簡單方式。與類別元件相比,函式式元件的語法更為簡潔且易於理解,其主要特點是可以使用 Hooks 來管理狀態和副作用。

以下是一個基本的函式式元件示例:

```javascript
import React, { useState } from ′react′;

const Counter = () => {
const [count, setCount] = useState(0);

return (
<div>
<p>當前計數: {count}</p>
<button onClick={() => setCount(count + 1)}>增加</button>
<button onClick={() => setCount(count - 1)}>減少</button>
</div>
);


function LocalStateComponent() {   const [count, setCount] = useState(0);    const increment = () => {     setCount(prevCount => prevCount + 1);   };    return (     

{count}

); }

React hooks 使功能性元件能夠處理更複雜的邏輯和狀態管理,這在傳統上是類別元件所專屬的領域。 useEffect hook 是一個強大的工具,用於管理副作用,而 useMemo 和 useCallback 則可以透過記憶化複雜函式和數值來防止不必要的重渲染。功能性元件與 Hooks 的結合讓開發者能夠以更簡潔且高效的方式構建應用程式。

function OptimizedComponent({ userId }) {   const user = useMemo(() => fetchUserById(userId), [userId]);   const handleClick = useCallback(() => {     console.log('Clicked!');   }, []);    return (     

User: {user.name}

); }

React元件選擇:函式元件與 Hooks 如何提升效能

因此,搭配 Hooks 的函式元件在撰寫更乾淨且高效的程式碼方面提供了顯著的優勢。隨著應用程式規模和複雜性的增加,利用這些現代技術能顯著提升效能。對於希望建立或最佳化網頁應用程式的企業而言,考慮專業的網頁應用開發機構是一個戰略性選擇,以確保高品質且高效率的軟體解決方案。

在 React 中,選擇正確的元件型別對於有效的專案管理和開發至關重要。類別元件特別適合需要詳細控制生命週期方法與管理元件層級中複雜互動的情境。當您需要明確訪問生命週期方法時,類別元件表現出色,它們提供結構化的生命週期鉤子來處理資料擷取或訂閱等任務。

透過函式元件和 Hooks 提升效能:函式元件搭配 Hooks 在大型且複雜的應用程式中展現優異的效能提升效果。採用這些現代技術可大幅改善程式碼可讀性、效率和維護性,對於追求高效能網頁應用程式的企業而言,至關重要。而頂尖 React 開發專家也強調了選擇適當元件型別的重要性。在許多情況下,函式元件因為可以透過 Hooks 輕鬆處理資料擷取及訂閱等任務,而簡化開發流程,因此展現出了更多優勢。

使用 componentDidMount 方法}

在 React 中,componentDidMount 是一個生命週期方法,當元件被首次渲染到 DOM 中後會自動呼叫。這個方法是處理副作用的理想場所,例如傳送網路請求以獲取資料或直接操作 DOM。

以下是一個簡單的範例,展示如何在 componentDidMount 中傳送 API 請求:

```javascript
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
data: null,
};


componentDidMount() {
fetch(′https://api.example.com/data′)
.then((response) => response.json())
.then((data) => this.setState({ data }))
.catch((error) => console.error(′Error fetching data:′, error));


render() {
const { data } = this.state;
return (
<div>
{data ? (
<pre>{JSON.stringify(data, null, 2)}</pre>
) : (
<p>Loading...</p>
)}
</div>
);



class UserData extends React.Component {   componentDidMount() {     this.fetchData();   }    fetchData = () => {     // API call to fetch user data   }    render() {     return 
Welcome to your profile!
; } }

當你的元件需要複雜的狀態邏輯或需與多個子元件互動時,使用類別元件是合適的選擇,因為它們具備強大的狀態管理能力。程式碼示例:管理複雜狀態

class ComplexComponent extends React.Component {   constructor(props) {     super(props);     this.state = {       part1: false,       part2: true,       combinedState: false     };   }    render() {     return (       
); } }

為了在元件樹的某一部分優雅地處理錯誤,必須使用類別元件。函式元件不支援錯誤邊界。程式碼範例:錯誤邊界

class ErrorBoundary extends React.Component {   constructor(props) {     super(props);     this.state = { hasError: false };   }    static getDerivedStateFromError(error) {     return { hasError: true };   }    render() {     if (this.state.hasError) {       return 

Something went wrong.

; } return this.props.children; } }

類別元件與功能性元件:在 React 中選擇最佳的元件方式

因此,類別元件在需要對生命週期進行精細控制、複雜狀態管理以及錯誤處理的 React 應用程式中是理想的選擇。它們提供了一種結構化的方法,雖然語法較為冗長,但在特定情境下帶來了明確的好處。相對而言,功能性元件則旨在簡化和提升效能。在許多現代 React 開發情境中,它們是最佳選擇,尤其當專案可以利用 Hooks 來進行狀態和生命週期管理時。功能性元件比類別元件更不繁瑣,也更易於維護。它們透過像 React.memo 這樣的最佳化技術以及 useMemo 和 useCallback 等 Hooks 幫助避免不必要的重新渲染。

功能性元件的優勢包括:
- 更簡單的語法:功能性元件使用直接的 JavaScript 函式,而無需類別語法中的複雜性。這使得它們更容易編寫和理解。

隨著 React 生態系統愈加成熟,函式式元件與類元件之間呈現出越來越明顯的趨勢轉變。未來開發者將不斷地迎接 Hooks 的挑戰,以實現更高效能和可維護性的程式碼。在深入探討函式式元件效能最佳化時,我們也不能忽視那些超越 React.memo 和 useMemo 的先進技術,它們為應用程式增添了更多可能性。因此,在選擇合適的組建方式時,我們必須考量專案的需求與長期發展方向,以便做出最佳決策。

程式碼片段:簡單的函式元件

function WelcomeMessage({ name }) {   return 
Hello, {name}!
; }

最佳化效能:透過避免類別元件的額外負擔,函式元件通常更輕量且執行速度更快。像是 useState 和 useEffect 這樣的 Hooks,使得狀態管理和副作用處理變得簡單易行。程式碼示例:使用 Hooks

function Counter() {   const [count, setCount] = useState(0);    useEffect(() => {     document.title = `You clicked ${count} times`;   });    return (        ); }

增強的可重用性:功能元件作為純函式,能夠輕鬆地進行重用和測試,從而減少程式碼庫中的冗餘。

功能元件在那些不過度依賴複雜狀態互動或不需要超出 hooks 所提供的生命週期方法的專案中,特別具有優勢。它們體現了現代 React 的明確資料流和簡約主義哲學,使其成為大多數應用程式的理想選擇,尤其是那些重視乾淨且易於維護的程式碼。類別元件對於需要進階功能(如錯誤邊界或複雜生命週期互動)的專案仍然具有重要意義和必要性。

React 函式元件:更簡潔、更強大的開發模式

在 React 中,類元件與函式元件的辯論非常重要,兩者各自擁有獨特的優勢,取決於 React 專案的需求。類元件因其結構堅固而聞名,非常適合需要複雜狀態管理和直接訪問生命週期方法的場景。React 類元件允許對元件生命週期進行詳細控制,使其適用於依賴於錯綜複雜狀態互動且需具備錯誤處理能力的更為複雜的應用。

相比之下,函式元件則提供了一種更現代化且精簡的方法。它們非常適合那些受益於較短、更易讀程式碼及較少副作用的專案。隨著 React hooks 的引入,函式元件現在可以有效地管理狀態並利用生命週期事件,提供傳統上僅限於類元件所具備的功能,但語法更為簡潔、效能也有所改善。

從效能最佳化與渲染最佳化方面來看,由於型別 React 元件本身存在著一定程度上的複雜性,因此在效能上可能會遇到瓶頸。而結合 Hooks 的函式元件則以其輕量級和無狀態特性,可以實現更快的渲染速度並降低記憶體佔用。例如,`useMemo` 和 `useCallback` 可以快取計算結果和回撥函式,有效避免不必要的重新計算,以減輕渲染壓力。

針對複雜狀態管理場景時,可以搭配 Redux 或 MobX 等狀態管理庫使用函式元件,以集中管理狀態並透過訂閱機制來最佳化渲染。這樣能夠有效避免不必要的重新渲染,提高整體效能。React 團隊持續投入資源於效能最佳化領域,在未來可能會推出更多基於函式元件的新方案,例如改進 Hooks 的機制、最佳化虛擬 DOM 比較策略以及提供針對效能最佳化的新工具。

總之,在選擇使用型別或函式元件時,需要根據專案需求仔細考量,而功能強大的 Hooks 使得未來開發趨勢愈加明朗,也將推動更高效、更靈活的開發模式出現。

React 元件開發最佳實踐:簡化、重用與效能提升

對於許多開發者和 React 團隊而言,選擇類別元件(class components)與函式元件(functional components)的考量,通常取決於應用程式的具體需求、個人或團隊的偏好,以及各種元件型別所提供的特定優勢。開發 React 元件需要一種平衡的方法,以維持可擴充套件性並確保可維護性。以下是一些適用於類別元件和函式元件的最佳實踐:

1. 最佳化元件重用性:設計能在整個應用程式中重複使用的元件,以減少冗餘並促進更簡單的維護。

2. 保持元件小巧且專注:將複雜的元件拆分為更小、更易管理的部分,每個部分僅處理一項功能。這種做法增強了可讀性和可測試性。

3. 明智地使用生命週期方法:在類別元件中,確保有效地使用生命週期方法來管理副作用;而在函式元件中,可以利用像 `useEffect` 這樣的 hooks 來處理副作用。

4. 在可能情況下本地管理狀態:盡量將狀態管理保持在最接近其所需的位置。只有在必要時才使用 React 的上下文 API 或狀態管理庫如 Redux,以避免不必要的屬性傳遞。

5. 引入型別檢查:使用 PropTypes 或 TypeScript 對應用程式中的型別進行檢查,以便早期捕捉錯誤並提高程式碼可維護性。

6. 利用 Hooks 寫出乾淨的函式元件:利用 hooks 處理狀態、上下文以及其他 React 特點,使函式元件更加精簡清晰。

遵循這些實踐可以顯著提升開發過程,使你的 React 應用程式更高效且隨著規模擴大而變得易於管理。不論你選擇類別還是函式元件,焦點始終應該放在撰寫清晰、可維護程式碼上,並符合現代開發標準。在當前的大型應用及複雜元件互動環境中,引入 `Suspense` 和 `lazy` 機制來最佳化效能也是至關重要的一步。透過這些技術,我們不僅能夠改善初始載入時間,還能提升整體使用者體驗,使我們的應用程式既快速又高效。

參考來源

ReactJS入門- React Component 元件. 元件的概念 - 碼農思考中/ Ted

本篇文章介紹了兩種元件的建立方式,我個人偏好於function 的方式建立元件,簡單明瞭。但是class 的方式建立是最符合物件導向設計的方式,可以用有元件 ...

來源: Medium

[react] 元件(component) | PJCHENder 未整理筆記

React 中的元件(component)是一個小而可重複使用的程式碼,每一個元件都必須從 Component 這個類別(class)而來,component class 就像是一個可以用來 ...

來源: PJCHENder

React Class-based vs Functional Component: 從特性淺談兩種寫法之 ...

React 要寫出一個元件,有 Class-based 或是 Functional 兩種方式,這篇文章會從寫法比較、元件特性、週期去談兩種寫法的差異,結論先直接推薦 ...

來源: 前端三分鐘

定義元件 - Pies Doc

在React 中,您可以使用類別(class) 或是函式(function) 來定義元件。兩者可以做到的事情幾乎相同,但由於函式元件不僅樣板程式碼(boilerplate) 較少,也 ...

來源: piesdoc.com

【React 學習】認識元件Component | 蕭宇廷的沙龍

元件(Component) 是React 的核心概念,不同的元件組成UI,有點像拼樂高一樣。以往我們都說HTML 是網頁的架構,再搭配CSS 進行美化以及JavaScript 添加 ...

來源: Vocus

建立React 元件(Component ) - iT 邦幫忙

建立元件. React元件有兩種建立方式,這篇會用Functional的方式來建立元件: Class-based 類別元件 ... Functional 函式元件(在16.8版React新增了新功能hook後,即讓函式元件 ...

來源: iT 邦幫忙

改用class Component | 從Hooks 開始,讓你的網頁React 起來

在React 中建立元件的方式有兩種,一種是使用函式(function)建立的,稱作function component;另一種則是使用類別(class)來建立的,稱作class component。

來源: PJCHENder

【React.js入門- 21】 各階層Component的溝通 - iT 邦幫忙

在使用component時,我們常會遇到不同元件需要互相傳資料、呼叫函式的情況,大致可分為: 子對父; 父對子; 子對子(同父的子類別之間); 祖先和某代孫子之間.

來源: iT 邦幫忙

J.D.

專家

相關討論

❖ 相關專欄