createElement
createElement
によって React 要素を作成できます。これは JSX を書く代わりの手段として利用できます。
const element = createElement(type, props, ...children)
リファレンス
createElement(type, props, ...children)
createElement
を呼び出して、指定した type
、props
、children
を持った React 要素を作成します。
import { createElement } from 'react';
function Greeting({ name }) {
return createElement(
'h1',
{ className: 'greeting' },
'Hello'
);
}
引数
-
type
:type
引数は有効な React のコンポーネント型でなければなりません。例えば、タグ名の文字列('div'
や'span'
)や、React コンポーネント(関数、クラス、またはFragment
のような特別なコンポーネント)が該当します。 -
props
:props
引数はオブジェクトかnull
でなければなりません。null
を渡すと、空のオブジェクトと同じように扱われます。React は、渡されたprops
と同じ props を持った要素を作成します。props
オブジェクトのref
とkey
は特別であり、返されたelement
のelement.props.ref
やelement.props.key
として利用できません。element.ref
ないしelement.key
となります。 -
省略可能
...children
: ゼロ個以上の子ノード。これらは React ノード、つまり、React 要素、文字列、数値、ポータル、空ノード(null
、undefined
、true
、false
)、あるいは React ノードの配列となります。
返り値
createElement
は以下のプロパティを持つ React 要素オブジェクトを返します。
type
: 指定したtype
。props
: 指定したprops
、ただしref
とkey
は除く。ref
: 指定したref
。未指定の場合はnull
。key
: 指定したkey
。強制的に文字列に変換されます。未指定の場合はnull
。
通常、この要素をコンポーネントから返すか、他の要素の子として用います。要素のプロパティを読み取ることは可能ですが、作成後は要素の構造を非公開 (opaque) として扱い、レンダーのみ行うようにするべきです。
注意点
-
React 要素とその props はイミュータブル (immutable) として扱い、作成後にその内容を変更してはなりません。これを強制するために、React は開発環境において、返された要素とその
props
プロパティを浅く凍結 (freeze) します。 -
JSX を使用する場合、独自のカスタムコンポーネントをレンダーするためにはタグを大文字で始める必要があります。つまり、
<Something />
はcreateElement(Something)
と同等ですが、<something />
(小文字)はcreateElement('something')
と同等です(文字列なので、組み込みの HTML タグとして扱われます)。 -
複数の子の内容がすべて静的に分かっている場合、
createElement
には子をcreateElement('h1', {}, child1, child2, child3)
のように複数の引数として渡してください。子が動的な場合は、配列全体を第 3 引数としてcreateElement('ul', {}, listItems)
のように渡してください。これにより、React は動的なリストにkey
が欠けている場合に警告を出すようになります。静的なリストでは並び替えは決して発生しないため、key は必要ありません。
使用法
JSX を使わずに要素を作成する
JSX が好きでない場合や、プロジェクトで使用できない場合には、代わりに createElement
を使用できます。
JSX を使わずに要素を作成するには、createElement
を呼び出して、何らかの type、props、children を引数として渡します。
import { createElement } from 'react';
function Greeting({ name }) {
return createElement(
'h1',
{ className: 'greeting' },
'Hello ',
createElement('i', null, name),
'. Welcome!'
);
}
children はオプションで、必要なだけ渡すことができます(上記の例では子が 3 つあります)。このコードは、<h1>
ヘッダに挨拶文字列を入れて表示します。比較のため、以下に JSX を使って書き直した同じ例を示します。
function Greeting({ name }) {
return (
<h1 className="greeting">
Hello <i>{name}</i>. Welcome!
</h1>
);
}
自身のカスタム React コンポーネントをレンダーするには、'h1'
のような文字列ではなく Greeting
のような関数を type として渡します。
export default function App() {
return createElement(Greeting, { name: 'Taylor' });
}
JSX を使用した場合は以下のようになります。
export default function App() {
return <Greeting name="Taylor" />;
}
以下は、createElement
を使用して書かれたフルのサンプルです。
import { createElement } from 'react'; function Greeting({ name }) { return createElement( 'h1', { className: 'greeting' }, 'Hello ', createElement('i', null, name), '. Welcome!' ); } export default function App() { return createElement( Greeting, { name: 'Taylor' } ); }
同じものを JSX で書くと以下のようになります。
function Greeting({ name }) { return ( <h1 className="greeting"> Hello <i>{name}</i>. Welcome! </h1> ); } export default function App() { return <Greeting name="Taylor" />; }
どちらのコーディングスタイルも問題ありませんので、プロジェクトに合わせて好きな方を使用してください。createElement
と比較して JSX を使用する場合の主な利点は、どの閉じタグがどの開きタグに対応しているかが簡単にわかることです。
さらに深く知る
要素 (element) とは、ユーザインターフェースの軽量な説明書きのことです。例えば、<Greeting name="Taylor" />
と createElement(Greeting, { name: 'Taylor' })
はいずれも、次のようなオブジェクトを生成します。
// Slightly simplified
{
type: Greeting,
props: {
name: 'Taylor'
},
key: null,
ref: null,
}
このオブジェクトを作成しただけでは、Greeting
コンポーネントがレンダーされたり、DOM 要素が作成されたりするわけではないことに注意してください。
React 要素とは、むしろ指示書のようなものです。React に後で Greeting
コンポーネントをレンダーするよう指示するものです。このオブジェクトを App
コンポーネントから返すことで、React に次に何をすべきかを伝えるのです。
要素の作成は非常に安価であるため、最適化したり避けたりする必要はありません。