) – React">

常見元件(例如 <div>)

所有內建瀏覽器元件,例如 <div>,都支援一些常見的屬性和事件。


參考

常見元件(例如 <div>

<div className="wrapper">Some content</div>

請參閱以下更多範例。

Props

這些特殊的 React props 支援所有內建元件

  • children:React 節點(元素、字串、數字、入口、空節點,例如 nullundefined 和布林值,或其他 React 節點的陣列)。指定元件內的內容。使用 JSX 時,通常會透過巢狀標籤(例如 <div><span /></div>)來隱含指定 children 屬性。

  • dangerouslySetInnerHTML:一個表單物件 { __html: '<p>some html</p>' } 內含原始 HTML 字串。覆寫 DOM 節點的 innerHTML 屬性,並在內部顯示傳遞的 HTML。這應該非常小心地使用!如果內部的 HTML 不可信(例如,如果它基於使用者資料),您就有可能引入 XSS 漏洞。深入了解使用 dangerouslySetInnerHTML

  • ref:來自 useRefcreateRef 的 ref 物件,或 ref 回呼函式,舊版 ref 的字串。您的 ref 會填入此節點的 DOM 元素。深入了解如何使用 ref 來處理 DOM。

  • suppressContentEditableWarning:布林值。如果為 true,會抑制 React 顯示的警告,針對同時具有 childrencontentEditable={true}(通常無法一起使用)的元素。如果您正在建置手動管理 contentEditable 內容的文字輸入法庫,請使用此功能。

  • suppressHydrationWarning:布林值。如果您使用 伺服器渲染,通常伺服器和用戶端呈現不同內容時會出現警告。在某些罕見情況下(例如時間戳記),很難或不可能保證完全匹配。如果您將 suppressHydrationWarning 設定為 true,React 就不會警告您該元素的屬性和內容不符。它只會作用於一層,並旨在作為逃生艙口使用。不要過度使用它。 了解如何抑制水合錯誤

  • style: An object with CSS styles, for example { fontWeight: 'bold', margin: 20 }. Similarly to the DOM style property, the CSS property names need to be written as camelCase, for example fontWeight instead of font-weight. You can pass strings or numbers as values. If you pass a number, like width: 100, React will automatically append px (“pixels”) to the value unless it’s a unitless property. We recommend using style only for dynamic styles where you don’t know the style values ahead of time. In other cases, applying plain CSS classes with className is more efficient. Read more about className and style.

這些標準 DOM 屬性也支援所有內建元件

您也可以傳遞自訂屬性作為 props,例如 mycustomprop="someValue"。這在與第三方程式庫整合時會很有用。自訂屬性名稱必須是小寫,且不能以 on 開頭。值會轉換為字串。如果您傳遞 nullundefined,自訂屬性將會被移除。

這些事件只會觸發 <form> 元素

這些事件僅對 <dialog> 元素觸發。與瀏覽器事件不同,它們會在 React 中冒泡

這些事件僅會觸發 <details> 元素。與瀏覽器事件不同,它們會在 React 中冒泡

These events fire for <img>, <iframe>, <object>, <embed>, <link>, and SVG <image> elements. Unlike browser events, they bubble in React:

這些事件會觸發資源,例如 <audio><video>。與瀏覽器事件不同,它們會在 React 中冒泡

注意事項

  • 您無法同時傳遞 childrendangerouslySetInnerHTML
  • 有些事件(例如 onAbortonLoad)不會在瀏覽器中冒泡,但在 React 中會冒泡。

ref 回呼函式

您可以將函式傳遞給 ref 屬性,而不是 ref 物件(例如 useRef 回傳的物件)。

<div ref={(node) => console.log(node)} />

請參閱使用 ref 回呼函式的範例。

<div> DOM 節點新增至畫面時,React 會呼叫你的 ref 回呼,並將 DOM node 作為參數。當該 <div> DOM 節點移除時,React 會呼叫你的 ref 回呼,並將 null 作為參數。

每當你傳遞一個不同的 ref 回呼時,React 也會呼叫你的 ref 回呼。在上方的範例中,(node) => { ... } 是在每次渲染時不同的函式。當你的元件重新渲染時,前一個函式會被呼叫,並將 null 作為參數,而下一個函式會被呼叫,並將 DOM 節點作為參數。

參數

  • node:DOM 節點或 null。當 ref 附加時,React 會傳遞 DOM 節點給您,當 ref 分離時,傳遞 null。除非您在每次渲染時傳遞相同的函式參照給 ref 回呼,否則回呼會在元件每次重新渲染時暫時分離並重新附加。

傳回

不要從 ref 回呼傳回任何東西。


React 事件物件

您的事件處理常式將會收到一個React 事件物件。它有時也稱為「合成事件」。

<button onClick={e => {
console.log(e); // React event object
}} />

它符合與基礎 DOM 事件相同的標準,但修正了一些瀏覽器的不一致性。

有些 React 事件不會直接對應到瀏覽器的原生事件。例如在 onMouseLeave 中,e.nativeEvent 將指向 mouseout 事件。具體對應關係不屬於公開 API 的一部分,且未來可能會變更。如果您出於某種原因需要基礎瀏覽器事件,請從 e.nativeEvent 中讀取它。

屬性

React 事件物件實作一些標準 Event 屬性

  • bubbles: 布林值。傳回事件是否會在 DOM 中冒泡。
  • cancelable:一個布林值。傳回事件是否可以取消。
  • currentTarget:一個 DOM 節點。傳回 React 樹中附加目前處理程序的節點。
  • defaultPrevented:一個布林值。傳回是否已呼叫 preventDefault
  • eventPhase:一個數字。傳回事件目前處於哪個階段。
  • isTrusted:一個布林值。傳回事件是否由使用者觸發。
  • target:一個 DOM 節點。傳回事件發生的節點(可能是遠端的子節點)。
  • timeStamp:一個數字。傳回事件發生的時間。

此外,React 事件物件提供下列屬性

  • nativeEvent:一個 DOM Event。原始瀏覽器事件物件。

方法

React 事件物件實作一些標準 Event 方法

此外,React 事件物件提供以下方法

  • isDefaultPrevented():傳回一個布林值,表示是否呼叫 preventDefault
  • isPropagationStopped():傳回一個布林值,表示是否呼叫 stopPropagation
  • persist():不與 React DOM 搭配使用。使用 React Native 時,呼叫此函式可在事件發生後讀取事件的屬性。
  • isPersistent():不與 React DOM 搭配使用。使用 React Native 時,傳回是否已呼叫 persist

注意事項

  • currentTargeteventPhasetargettype 的值反映了 React 程式碼預期的值。在底層,React 會在根部附加事件處理常式,但這不會反映在 React 事件物件中。例如,e.currentTarget 可能與底層 e.nativeEvent.currentTarget 不同。對於多型填充事件,e.type(React 事件類型)可能與 e.nativeEvent.type(底層類型)不同。

AnimationEvent 處理常式函式

一個事件處理類型,用於 CSS 動畫 事件。

<div
onAnimationStart={e => console.log('onAnimationStart')}
onAnimationIteration={e => console.log('onAnimationIteration')}
onAnimationEnd={e => console.log('onAnimationEnd')}
/>

參數


ClipboardEvent 處理函式

一個事件處理類型,用於 剪貼簿 API 事件。

<input
onCopy={e => console.log('onCopy')}
onCut={e => console.log('onCut')}
onPaste={e => console.log('onPaste')}
/>

參數


CompositionEvent 處理函數

輸入法編輯器 (IME) 事件的事件處理類型 (IME)

<input
onCompositionStart={e => console.log('onCompositionStart')}
onCompositionUpdate={e => console.log('onCompositionUpdate')}
onCompositionEnd={e => console.log('onCompositionEnd')}
/>

參數


DragEvent 處理函式

HTML 拖放 API 事件的事件處理常式類型。

<>
<div
draggable={true}
onDragStart={e => console.log('onDragStart')}
onDragEnd={e => console.log('onDragEnd')}
>
Drag source
</div>

<div
onDragEnter={e => console.log('onDragEnter')}
onDragLeave={e => console.log('onDragLeave')}
onDragOver={e => { e.preventDefault(); console.log('onDragOver'); }}
onDrop={e => console.log('onDrop')}
>
Drop target
</div>
</>

參數


FocusEvent 處理函式

焦點事件的事件處理函式類型。

<input
onFocus={e => console.log('onFocus')}
onBlur={e => console.log('onBlur')}
/>

請參閱範例。

參數


事件 處理函式

一般事件的事件處理類型。

參數


InputEvent 處理函數

onBeforeInput 事件的事件處理常式類型。

<input onBeforeInput={e => console.log('onBeforeInput')} />

參數


KeyboardEvent 處理函數

鍵盤事件的事件處理常式類型。

<input
onKeyDown={e => console.log('onKeyDown')}
onKeyUp={e => console.log('onKeyUp')}
/>

請參閱範例。

參數


MouseEvent 處理函式

滑鼠事件的事件處理常式。

<div
onClick={e => console.log('onClick')}
onMouseEnter={e => console.log('onMouseEnter')}
onMouseOver={e => console.log('onMouseOver')}
onMouseDown={e => console.log('onMouseDown')}
onMouseUp={e => console.log('onMouseUp')}
onMouseLeave={e => console.log('onMouseLeave')}
/>

請參閱範例。

參數


PointerEvent 處理函式

一個 指標事件 的事件處理類型。

<div
onPointerEnter={e => console.log('onPointerEnter')}
onPointerMove={e => console.log('onPointerMove')}
onPointerDown={e => console.log('onPointerDown')}
onPointerUp={e => console.log('onPointerUp')}
onPointerLeave={e => console.log('onPointerLeave')}
/>

請參閱範例。

參數


TouchEvent 處理函式

事件處理類型,用於 觸控事件。

<div
onTouchStart={e => console.log('onTouchStart')}
onTouchMove={e => console.log('onTouchMove')}
onTouchEnd={e => console.log('onTouchEnd')}
onTouchCancel={e => console.log('onTouchCancel')}
/>

參數


TransitionEvent 處理函式

CSS 轉場事件的事件處理類型。

<div
onTransitionEnd={e => console.log('onTransitionEnd')}
/>

參數


UIEvent 處理函式

一般 UI 事件的事件處理常式類型。

<div
onScroll={e => console.log('onScroll')}
/>

參數


WheelEvent 處理函式

事件處理類型為 onWheel 事件。

<div
onWheel={e => console.log('onWheel')}
/>

參數


用法

套用 CSS 樣式

在 React 中,您可以使用 className 指定 CSS 類別。它的作用類似於 HTML 中的 class 屬性

<img className="avatar" />

然後你在一個獨立的 CSS 檔案中為它撰寫 CSS 規則

/* In your CSS */
.avatar {
border-radius: 50%;
}

React 沒有規定你如何新增 CSS 檔案。在最簡單的情況下,你會在你的 HTML 中新增一個 <link> 標籤。如果你使用建置工具或框架,請參閱其文件以了解如何將 CSS 檔案新增到你的專案。

有時,樣式值取決於資料。使用 style 屬性來動態傳遞一些樣式

<img
className="avatar"
style={{
width: user.imageSize,
height: user.imageSize
}}
/>

在上述範例中,style={{}} 不是一個特殊的語法,而是一個常規的 {} 物件,位於 style={ } JSX 大括號。 我們建議僅在你樣式取決於 JavaScript 變數時才使用 style 屬性。

export default function Avatar({ user }) {
  return (
    <img
      src={user.imageUrl}
      alt={'Photo of ' + user.name}
      className="avatar"
      style={{
        width: user.imageSize,
        height: user.imageSize
      }}
    />
  );
}

深入探討

如何有條件地套用多個 CSS 類別?

若要根據條件套用 CSS 類別,您需要使用 JavaScript 自行產生 className

例如,className={'row ' + (isSelected ? 'selected': '')} 將產生 className="row"className="row selected",視 isSelected 是否為 true 而定。

若要讓這更具可讀性,您可以使用一個微型的輔助函式庫,例如 classnames:

import cn from 'classnames';

function Row({ isSelected }) {
return (
<div className={cn('row', isSelected && 'selected')}>
...
</div>
);
}

如果您有多個條件式類別,這將特別方便

import cn from 'classnames';

function Row({ isSelected, size }) {
return (
<div className={cn('row', {
selected: isSelected,
large: size === 'large',
small: size === 'small',
})}>
...
</div>
);
}

使用 ref 操作 DOM 節點

有時,您需要取得與 JSX 中標籤相關聯的瀏覽器 DOM 節點。例如,當按一下按鈕時,如果您想要將焦點放在 <input> 上,您需要在瀏覽器 <input> DOM 節點上呼叫 focus()

若要取得標籤的瀏覽器 DOM 節點,宣告一個 ref,並將其傳遞為該標籤的 ref 屬性

import { useRef } from 'react';

export default function Form() {
const inputRef = useRef(null);
// ...
return (
<input ref={inputRef} />
// ...

在 React 呈現在螢幕上後,它會將 DOM 節點放入 inputRef.current 中。

import { useRef } from 'react';

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <>
      <input ref={inputRef} />
      <button onClick={handleClick}>
        Focus the input
      </button>
    </>
  );
}

閱讀更多關於 使用 refs 操縱 DOM查看更多範例。

對於更進階的使用案例,ref 屬性也接受 回呼函式。


危險地設定內部 HTML

你可以將原始 HTML 字串傳遞給元素,如下所示

const markup = { __html: '<p>some raw html</p>' };
return <div dangerouslySetInnerHTML={markup} />;

這很危險。與底層 DOM innerHTML 屬性一樣,你必須非常小心!除非標記來自完全可信賴的來源,否則很容易以這種方式引入 XSS 漏洞。

例如,如果您使用將 Markdown 轉換為 HTML 的 Markdown 函式庫,您相信其剖析器不包含錯誤,且使用者只看到自己的輸入,您可以像這樣顯示產生的 HTML

import { Remarkable } from 'remarkable';

const md = new Remarkable();

function renderMarkdownToHTML(markdown) {
  // This is ONLY safe because the output HTML
  // is shown to the same user, and because you
  // trust this Markdown parser to not have bugs.
  const renderedHTML = md.render(markdown);
  return {__html: renderedHTML};
}

export default function MarkdownPreview({ markdown }) {
  const markup = renderMarkdownToHTML(markdown);
  return <div dangerouslySetInnerHTML={markup} />;
}

{__html} 物件應儘可能建立在 HTML 產生的附近,就像上述範例在 renderMarkdownToHTML 函式中所做的那樣。這可確保在您的程式碼中使用的所有原始 HTML 都明確標記為原始 HTML,而且只有您預期包含 HTML 的變數會傳遞給 dangerouslySetInnerHTML。不建議像 <div dangerouslySetInnerHTML={{__html: markup}} /> 一樣在內嵌中建立物件。

若要了解為什麼呈現任意 HTML 很危險,請將上述程式碼替換為以下內容

const post = {
// Imagine this content is stored in the database.
content: `<img src="" onerror='alert("you were hacked")'>`
};

export default function MarkdownPreview() {
// 🔴 SECURITY HOLE: passing untrusted input to dangerouslySetInnerHTML
const markup = { __html: post.content };
return <div dangerouslySetInnerHTML={markup} />;
}

嵌入在 HTML 中的程式碼會執行。駭客可能利用此安全漏洞竊取使用者資訊或執行使用者代碼的動作。僅使用 dangerouslySetInnerHTML 與受信任且已清除的資料。


處理滑鼠事件

此範例顯示一些常見的 滑鼠事件 及其觸發時機。

export default function MouseExample() {
  return (
    <div
      onMouseEnter={e => console.log('onMouseEnter (parent)')}
      onMouseLeave={e => console.log('onMouseLeave (parent)')}
    >
      <button
        onClick={e => console.log('onClick (first button)')}
        onMouseDown={e => console.log('onMouseDown (first button)')}
        onMouseEnter={e => console.log('onMouseEnter (first button)')}
        onMouseLeave={e => console.log('onMouseLeave (first button)')}
        onMouseOver={e => console.log('onMouseOver (first button)')}
        onMouseUp={e => console.log('onMouseUp (first button)')}
      >
        First button
      </button>
      <button
        onClick={e => console.log('onClick (second button)')}
        onMouseDown={e => console.log('onMouseDown (second button)')}
        onMouseEnter={e => console.log('onMouseEnter (second button)')}
        onMouseLeave={e => console.log('onMouseLeave (second button)')}
        onMouseOver={e => console.log('onMouseOver (second button)')}
        onMouseUp={e => console.log('onMouseUp (second button)')}
      >
        Second button
      </button>
    </div>
  );
}


處理指標事件

這個範例顯示一些常見的 指標事件 以及它們觸發的時間。

export default function PointerExample() {
  return (
    <div
      onPointerEnter={e => console.log('onPointerEnter (parent)')}
      onPointerLeave={e => console.log('onPointerLeave (parent)')}
      style={{ padding: 20, backgroundColor: '#ddd' }}
    >
      <div
        onPointerDown={e => console.log('onPointerDown (first child)')}
        onPointerEnter={e => console.log('onPointerEnter (first child)')}
        onPointerLeave={e => console.log('onPointerLeave (first child)')}
        onPointerMove={e => console.log('onPointerMove (first child)')}
        onPointerUp={e => console.log('onPointerUp (first child)')}
        style={{ padding: 20, backgroundColor: 'lightyellow' }}
      >
        First child
      </div>
      <div
        onPointerDown={e => console.log('onPointerDown (second child)')}
        onPointerEnter={e => console.log('onPointerEnter (second child)')}
        onPointerLeave={e => console.log('onPointerLeave (second child)')}
        onPointerMove={e => console.log('onPointerMove (second child)')}
        onPointerUp={e => console.log('onPointerUp (second child)')}
        style={{ padding: 20, backgroundColor: 'lightblue' }}
      >
        Second child
      </div>
    </div>
  );
}


處理焦點事件

在 React 中,焦點事件會冒泡。你可以使用 currentTargetrelatedTarget 來區分聚焦或失焦事件是否來自於父元素外部。範例顯示如何偵測聚焦子元素、聚焦父元素,以及如何偵測焦點進入或離開整個子樹。

export default function FocusExample() {
  return (
    <div
      tabIndex={1}
      onFocus={(e) => {
        if (e.currentTarget === e.target) {
          console.log('focused parent');
        } else {
          console.log('focused child', e.target.name);
        }
        if (!e.currentTarget.contains(e.relatedTarget)) {
          // Not triggered when swapping focus between children
          console.log('focus entered parent');
        }
      }}
      onBlur={(e) => {
        if (e.currentTarget === e.target) {
          console.log('unfocused parent');
        } else {
          console.log('unfocused child', e.target.name);
        }
        if (!e.currentTarget.contains(e.relatedTarget)) {
          // Not triggered when swapping focus between children
          console.log('focus left parent');
        }
      }}
    >
      <label>
        First name:
        <input name="firstName" />
      </label>
      <label>
        Last name:
        <input name="lastName" />
      </label>
    </div>
  );
}


處理鍵盤事件

這個範例顯示一些常見的 鍵盤事件 以及它們觸發的時間。

export default function KeyboardExample() {
  return (
    <label>
      First name:
      <input
        name="firstName"
        onKeyDown={e => console.log('onKeyDown:', e.key, e.code)}
        onKeyUp={e => console.log('onKeyUp:', e.key, e.code)}
      />
    </label>
  );
}