React 的類型系統與 TypeScript 一起使用時,為開發人員提供了建構類型安全應用程式的強大框架。了解各種 React 類型之間的細微差別對於就其使用做出明智的決策至關重要。讓我們深入詳細比較這些類型,以了解它們的差異和適當的用例。
React.FC是React中專門用來定義函數元件的類型。當 React Hooks 被引入並廣泛採用時,它開始變得更加流行。
在 React 18 之前,它曾經包含一個隱式的children屬性,使其適合預期有孩子的元件。但很長一段時間以來,隱式的children prop類型已經根據React 18的類型變化被刪除了。
這是一個使用範例:
interface SomeComponentProps {
title: string;
children?: React.ReactNode;
}
export const SomeComponent: React.FC<SomeComponentProps> = ({ title, children }) => {
return (
<article>
<h2>{title}</h2>
{children}
</article>
);
};
然而,由於刪除了隱children prop 類型,現在使用React.FC的人少了很多,因為與直接將介面分配給 props 物件相比,它很笨重並且沒有提供任何真正的好處:
interface SomeComponentProps {
title: string;
children?: React.ReactNode;
}
export const SomeComponent = ({ title, children }: SomeComponentProps) => {
return (
<article>
<h2>{title}</h2>
{children}
</article>
);
};
另一方面, React.ElementType是一種更廣泛的類型,表示可以由 React 呈現的任何元件類型。這不僅包括 React 函數和類別元件,還包括 HTML 元素的字串標籤(例如「div」、「span」)。當您想要接受元件作為 prop 並渲染它時, React.ElementType特別有用,允許動態元件使用。
const DynamicComponent: React.ElementType = 'div';
export const Container = () => (
<DynamicComponent className="container">Hello, world!</DynamicComponent>
);
在這裡, DynamicComponent的類型為React.ElementType ,允許它動態分配給不同類型的元件或 HTML 元素。
React.FC主要用於定義功能元件。從 React 18 開始,它不再那麼有用了。
React.ElementType在接受各種可渲染實體方面提供了更大的靈活性。當您需要可以動態接受不同類型的 React 元件或 HTML 元素的東西時,請使用React.ElementType
React.ReactElement是一個具有type 、 props和key屬性的物件,由React.createElement()函數建立。與React.ReactNode相比,它是一種更具體的類型,表示可以由 React 直接渲染的元素。
const elementContent: React.ReactElement = <div>Hello, React.ReactElement!</div>;
export const Container = () => <>{elementContent}</>;
React.ReactNode是最具包容性的類型,代表任何可以由 React 渲染的東西。這包括原始類型(字串、數字、布林值)、 JSX.Element 、 React.ReactElement 、這些類型的陣列等等。這是道具的首選類型,可以接受各種內容,例如children 。
const multiElementContent: React.ReactNode = (
<div>
<p>This is a paragraph.</p>
{'This is a text node.'}
{null}
</div>
);
const primitiveTypeContent: React.ReactNode = "I'm a primitive-type React.ReactNode";
export const Container = () => {
return (
<>
{multiElementContent}
{primitiveTypeContent}
</>
);
};
下面的維恩圖描述了React.ReactNode和React.ReactElement之間的關係:

JSX.Element本質上是一個具有更廣泛定義的React.ReactElement ,允許各種程式庫以自己的方式實作 JSX。它是 TypeScript 內部使用的類型,用於表示 JSX 表達式的傳回類型。
const jsxElement: JSX.Element = <span>Hello, JSX.Element!</span>;
export const Container = () => <>{jsxElement}</>;
React.ReactNode是最靈活、最具包容性的,適合像孩子一樣可以接受多樣化內容的打字props。
React.ReactElement和JSX.Element更具體, React.ReactElement適用於 React 建立的元素,而JSX.Element適用於使用 JSX 語法定義的元素。
React.ReactNode或React.ReactElement / JSX.Element 。基本上,函陣列件可以理解為:type ReactFC<P = {}> = (props: P) => React.ReactNode;
const MyComponent = ({ children }: { children: React.ReactNode }) => {
return <div>{children}</div>;
};
export const App = () => {
return (
<div>
<MyComponent>
Rendering MyComponent with <strong>JSX Syntax</strong>
</MyComponent>
</div>
);
}
是相同的:
const MyComponent = ({ children }: { children: React.ReactNode }) => {
return <div>{children}</div>;
};
export const App = () => {
return (
<div>
{MyComponent({
children: (
<>
Rendering MyComponent by
<strong>Invoking Function Component</strong>
</>
),
})}
</div>
);
}
了解這些 React 類型和介面之間的差異可以讓開發人員做出更明智的決策,從而產生更乾淨、更易於維護的程式碼。無論您是定義元件、接受動態內容還是處理子元件,選擇正確的類型對於充分發揮 React 和 TypeScript 的潛力至關重要。
請期待我即將發表的文章,這些文章將更深入地探討利用這些類型的理解的模式。