Skip to content

Latest commit

 

History

History
1202 lines (930 loc) · 86.2 KB

File metadata and controls

1202 lines (930 loc) · 86.2 KB
title <div> などの一般的なコンポーネント

<div> などすべての組み込みブラウザコンポーネントは、いくつかの共通の props とイベントをサポートしています。


リファレンス {/reference/}

<div> などの一般的なコンポーネント {/common/}

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

さらに例を見る

props {/common-props/}

これらの特別な React の props はすべての組み込みコンポーネントでサポートされています。

  • children: React ノード(要素、文字列、数値、ポータルnullundefined やブーリアンのような空ノード、あるいは他の React ノードの配列)。コンポーネントの内容を指定します。JSX を使用する場合、通常は <div><span /></div> のようにタグをネストすることで props として暗黙的に children を指定します。

  • dangerouslySetInnerHTML: { __html: '<p>some html</p>' } という形式の、内部に生の HTML 文字列を含んだオブジェクト。DOM ノードの innerHTML プロパティを上書きし、渡された HTML を表示します。これは最大限に注意して使用する必要があります! 内部の HTML が信頼できない場合(例えば、ユーザデータに基づいている場合)、XSS 脆弱性を導入するリスクがあります。dangerouslySetInnerHTML の使用について詳しく読む

  • ref: useRef または createRef から得られる ref オブジェクト、または ref コールバック関数、またはレガシー ref 用の文字列。指定された ref にこのノードの DOM 要素が渡されます。ref を使った DOM の操作について詳しく読む

  • suppressContentEditableWarning: ブーリアン値。true の場合、React が childrencontentEditable={true} を両方持つ要素(通常、これらは一緒に動作しません)に対して表示する警告を抑止します。contentEditable の内容を手動で管理するテキスト入力ライブラリを作成している場合に使用します。

  • suppressHydrationWarning: ブーリアン値。サーバレンダリングを使用する場合、通常、サーバとクライアントが異なる内容をレンダーすると警告が表示されます。一部の稀なケース(タイムスタンプなど)では、完全な一致を保証することが非常に困難または不可能です。suppressHydrationWarningtrue に設定すると、React はその要素の属性と内容の不一致について警告しなくなります。これは 1 レベルの深さまでしか機能せず、避難ハッチとして使用することを目的としています。過度な使用はしないでください。ハイドレーションエラーの抑制について読む

  • style: CSS スタイルを持つオブジェクト。例えば { fontWeight: 'bold', margin: 20 } のようなものです。DOM の style プロパティと同様に、CSS プロパティ名は camelCase で記述する必要があります。例えば font-weight ではなく fontWeight と書きます。値として文字列や数値を渡すことができます。数値を渡す場合、例えば width: 100 のようにすると、React は自動的に px("ピクセル")を値に追加します。ただし、それが単位のないプロパティの場合は除きます。style は、スタイルの値が事前に分からない動的なスタイルに対してのみ使用することを推奨します。他の場合は、className を用いてプレーンな CSS クラスを適用する方が効率的です。classNamestyle について詳しく読む

以下の標準的な DOM プロパティは、すべての組み込みコンポーネントでサポートされています。

カスタム属性も props として渡すことができます。例えば mycustomprop="someValue" のようになります。これはサードパーティのライブラリと統合する際に便利です。カスタム属性名は小文字でなければならず、on で始まってはいけません。値は文字列に変換されます。null または undefined を渡すと、カスタム属性は削除されます。

以下のイベントは <form> 要素のみで発火します:

以下のイベントは、<dialog> 要素に対してのみ発火します。ブラウザのイベントとは異なり、React ではバブルします。

以下のイベントは、<details> 要素に対してのみ発火します。ブラウザのイベントとは異なり、React ではバブルします。

これらのイベントは、<img><iframe><object><embed><link>、および SVG の <image> 要素に対して発火します。ブラウザのイベントとは異なり、React ではバブルします。

以下のイベントは、<audio><video> などのリソースに対して発火します。ブラウザのイベントとは異なり、React ではこれらのイベントはバブルします。

注意点 {/common-caveats/}

  • childrendangerouslySetInnerHTML を同時に渡すことはできません。
  • 一部のイベント(onAbortonLoad など)はブラウザではバブルしませんが、React ではバブルします。

ref コールバック関数 {/ref-callback/}

useRef などが返す ref オブジェクトの代わりに、ref 属性に関数を渡すことができます。

<div ref={(node) => {
  console.log('Attached', node);

  return () => {
    console.log('Clean up', node)
  }
}}>

ref コールバックを使用した例を見る

<div> DOM ノードが画面に追加されると、React はその DOM node を引数として ref コールバックを呼び出します。<div> DOM ノードが削除されると、React はコールバックが返したクリーンアップ関数を呼び出します。

React は、異なる ref コールバックが渡された場合も ref コールバックを呼び出します。上記の例では、(node) => { ... } は毎回のレンダーで異なる関数です。コンポーネントが再レンダーされると、の関数が null を引数として呼び出され、の関数が DOM ノードを引数として呼び出されます。

引数 {/ref-callback-parameters/}

  • node: DOM ノード。ref がアタッチされるときに React は DOM ノードを渡します。毎回のレンダーで ref コールバックに同じ関数参照を渡さない限り、コンポーネントのレンダー毎に一時的なクリーンアップと再作成が繰り返されることになります。

ref コールバックのクリーンアップは React 19 で追加されました {/react-19-added-cleanup-functions-for-ref-callbacks/}

後方互換性をサポートするため、ref コールバックからクリーンアップ関数が返されない場合、ref がデタッチされると nodenull としてコールバックが呼び出されます。この動作は将来のバージョンで削除される予定です。

返り値 {/returns/}

  • 省略可能 クリーンアップ関数:ref がデタッチされると、React はクリーンアップ関数を呼び出します。ref コールバックが関数を返さない場合、ref がデタッチされたときに、React は null を引数として再度コールバックを呼び出しますが、この動作は将来のバージョンで削除される予定です。

注意事項 {/caveats/}

  • Strict Mode が有効の場合、React は最終的なセットアップの前に、開発時専用のセットアップ+クリーンアップのサイクルを追加で 1 回実行します。これはクリーンアップのロジックがセットアップロジックに「鏡のように対応」しており、セットアップが行っていることが何であれそれの停止ないし取り消しを行っている、ということを保証するために行う、ストレステストです。問題が生じている場合は正しくクリーンアップ関数を実装してください。
  • 異なる ref のコールバックを渡した場合、React は古いコールバックのクリーンアップが存在する場合それをまず実行します。クリーンアップ関数が定義されていない場合は、ref コールバック自体が null を引数にして呼び出されます。その後新しい関数が、DOM ノードを引数にして呼び出されます。

React イベントオブジェクト {/react-event-object/}

イベントハンドラは React イベントオブジェクトを受け取ります。これは "合成イベント (synthetic event)" とも呼ばれることがあります。

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

これは対応する元の DOM イベントと同じ標準に準拠していますが、一部のブラウザ間の非一致を修正したものです。

一部の React イベントはブラウザのネイティブイベントに直接マッピングされません。例えば onMouseLeave においては e.nativeEventmouseout イベントになっています。具体的なマッピングは公開 API の一部ではなく、将来変更される可能性があります。何らかの理由で元となるブラウザイベントが必要な場合は、e.nativeEvent から読み取ってください。

プロパティ {/react-event-object-properties/}

React イベントオブジェクトは、標準の Event プロパティの一部を実装しています。

  • bubbles: ブーリアン。イベントが DOM をバブルするかどうかを返します。
  • cancelable: ブーリアン。イベントがキャンセル可能かどうかを返します。
  • currentTarget: DOM ノード。React ツリー内で現在のハンドラがアタッチされているノードを返します。
  • defaultPrevented: ブーリアン。preventDefault が呼び出されたかどうかを返します。
  • eventPhase: 数値。イベントが現在どのフェーズにあるかを返します。
  • isTrusted: ブーリアン。イベントの発生理由がユーザによるものかどうかを返します。
  • target: DOM ノード。イベントが発生したノード(遠い子孫要素のこともある)を返します。
  • timeStamp: 数値。イベントが発生した時間を返します。

さらに、React イベントオブジェクトは以下のプロパティを提供します。

  • nativeEvent: DOM の Event。オリジナルのブラウザイベントオブジェクト。

メソッド {/react-event-object-methods/}

React イベントオブジェクトは、標準の Event メソッドの一部を実装しています。

  • preventDefault(): イベントのデフォルトのブラウザアクションを防ぎます。
  • stopPropagation(): React ツリーを通じたイベントの伝播を停止します。

さらに、React イベントオブジェクトは以下のメソッドを提供します。

  • isDefaultPrevented(): preventDefault が呼び出されたかどうかを示すブーリアンを返します。
  • isPropagationStopped(): stopPropagation が呼び出されたかどうかを示すブーリアンを返します。
  • persist(): React DOM では使用されません。React Native では、イベントのプロパティを読み取る際にこのイベントを呼び出します。
  • isPersistent(): React DOM では使用されません。React Native では、persist が呼び出されたかどうかを返します。

注意点 {/react-event-object-caveats/}

  • currentTargeteventPhasetargettype の値は、あなたの React コードで期待される通りの値を反映しています。内部的には、React はルートにイベントハンドラをアタッチするのですが、この事実は React イベントオブジェクトには反映されません。例えば、e.currentTarget は元となる e.nativeEvent.currentTarget とは同じでないかもしれません。ポリフィルされたイベントでは、e.type(React イベントのタイプ)は e.nativeEvent.type(元イベントのタイプ)と異なることがあります。

AnimationEvent ハンドラ関数 {/animationevent-handler/}

CSS アニメーションイベントのイベントハンドラタイプです。

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

引数 {/animationevent-handler-parameters/}


ClipboardEvent ハンドラ関数 {/clipboadevent-handler/}

Clipboard API イベントのイベントハンドラタイプです。

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

引数 {/clipboadevent-handler-parameters/}


CompositionEvent ハンドラ関数 {/compositionevent-handler/}

インプットメソッドエディタ (IME) イベントのためのイベントハンドラタイプです。

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

引数 {/compositionevent-handler-parameters/}


DragEvent ハンドラ関数 {/dragevent-handler/}

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>
</>

引数 {/dragevent-handler-parameters/}


FocusEvent ハンドラ関数 {/focusevent-handler/}

フォーカスイベントのためのイベントハンドラタイプです。

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

例を見る

引数 {/focusevent-handler-parameters/}


Event ハンドラ関数 {/event-handler/}

一般的なイベントのためのイベントハンドラタイプです。

引数 {/event-handler-parameters/}


InputEvent ハンドラ関数 {/inputevent-handler/}

onBeforeInput イベントのためのイベントハンドラタイプです。

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

引数 {/inputevent-handler-parameters/}


KeyboardEvent ハンドラ関数 {/keyboardevent-handler/}

キーボードイベントのためのイベントハンドラタイプです。

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

例を見る

引数 {/keyboardevent-handler-parameters/}


MouseEvent ハンドラ関数 {/mouseevent-handler/}

マウスイベントのためのイベントハンドラタイプです。

<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')}
/>

例を見る

引数 {/mouseevent-handler-parameters/}


PointerEvent ハンドラ関数 {/pointerevent-handler/}

ポインタイベントのためのイベントハンドラタイプです。

<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')}
/>

例を見る

引数 {/pointerevent-handler-parameters/}


TouchEvent ハンドラ関数 {/touchevent-handler/}

タッチイベントのためのイベントハンドラタイプです。

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

引数 {/touchevent-handler-parameters/}


TransitionEvent ハンドラ関数 {/transitionevent-handler/}

CSS トランジションイベントのためのイベントハンドラタイプです。

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

引数 {/transitionevent-handler-parameters/}


UIEvent ハンドラ関数 {/uievent-handler/}

一般的な UI イベントのためのイベントハンドラタイプです。

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

引数 {/uievent-handler-parameters/}


WheelEvent ハンドラ関数 {/wheelevent-handler/}

onWheel イベントのためのイベントハンドラタイプです。

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

引数 {/wheelevent-handler-parameters/}


使用法 {/usage/}

CSS スタイルの適用 {/applying-css-styles/}

React では、CSS クラスを className で指定します。これは 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 属性を使用することをお勧めします。

import Avatar from './Avatar.js';

const user = {
  name: 'Hedy Lamarr',
  imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg',
  imageSize: 90,
};

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

複数の CSS クラスを条件付きで適用する方法 {/how-to-apply-multiple-css-classes-conditionally/}

CSS クラスを条件付きで適用するには、JavaScript を使用して className 文字列を自分で生成する必要があります。

例えば、className={'row ' + (isSelected ? 'selected': '')}isSelectedtrue かどうかによって、className="row" または className="row selected" になります。

これをより読みやすくするために、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 ノードを操作する {/manipulating-a-dom-node-with-a-ref/}

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>
    </>
  );
}

ref を使った DOM の操作に詳しい解説があります。こちらに他の例があります

より高度なユースケースのために、ref 属性はコールバック関数も受け入れます。


危険を冒して内部 HTML をセットする {/dangerously-setting-the-inner-html/}

以下のように、要素に対して生の HTML 文字列を渡すことができます。

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

これは危険です。元の DOM の innerHTML プロパティも同様ですが、最大限に注意を払ってください! マークアップが完全に信頼できるソースから来ていない限り、この方法を使うといとも簡単に XSS 脆弱性が発生します

例えば、Markdown を HTML に変換する Markdown ライブラリを使用しており、そのパーサにバグがないと信頼でき、ユーザは本人が入力したものしか見ない、という場合、結果 HTML を以下のように表示することができます。

import { useState } from 'react';
import MarkdownPreview from './MarkdownPreview.js';

export default function MarkdownEditor() {
  const [postContent, setPostContent] = useState('_Hello,_ **Markdown**!');
  return (
    <>
      <label>
        Enter some markdown:
        <textarea
          value={postContent}
          onChange={e => setPostContent(e.target.value)}
        />
      </label>
      <hr />
      <MarkdownPreview markdown={postContent} />
    </>
  );
}
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} />;
}
{
  "dependencies": {
    "react": "latest",
    "react-dom": "latest",
    "react-scripts": "latest",
    "remarkable": "2.0.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}
textarea { display: block; margin-top: 5px; margin-bottom: 10px; }

この {__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 は信頼できる、そしてサニタイズされたデータでのみ使用してください


マウスイベントの処理 {/handling-mouse-events/}

この例では、一般的なマウスイベントとそれらの発火タイミングを示しています。

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>
  );
}
label { display: block; }
input { margin-left: 10px; }

ポインタイベントの処理 {/handling-pointer-events/}

この例では、一般的なポインタイベントとそれらの発火タイミングを示しています。

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>
  );
}
label { display: block; }
input { margin-left: 10px; }

フォーカスイベントの処理 {/handling-focus-events/}

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>
  );
}
label { display: block; }
input { margin-left: 10px; }

キーボードイベントの処理 {/handling-keyboard-events/}

この例では、一般的なキーボードイベントとそれらの発火タイミングを示しています。

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>
  );
}
label { display: block; }
input { margin-left: 10px; }